- Don't force spew level debug messages on the kherpi
[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                         error(state, ins, "Load address out of bounds");
9874                 }
9875
9876                 memset(buffer, 0, sizeof(buffer));
9877                 memcpy(buffer, src, bits_to_bytes(mem_size));
9878
9879                 switch(mem_size) {
9880                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9881                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9882                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9883                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9884                 default:
9885                         internal_error(state, ins, "mem_size: %d not handled",
9886                                 mem_size);
9887                         val = 0;
9888                         break;
9889                 }
9890                 mkconst(state, ins, val);
9891         }
9892 }
9893
9894 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9895 {
9896         if (is_simple_const(RHS(ins, 0))) {
9897                 ulong_t val;
9898                 ulong_t mask;
9899                 val = read_const(state, ins, RHS(ins, 0));
9900                 mask = 1;
9901                 mask <<= ins->u.bitfield.size;
9902                 mask -= 1;
9903                 val >>= ins->u.bitfield.offset;
9904                 val &= mask;
9905                 mkconst(state, ins, val);
9906         }
9907 }
9908
9909 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9910 {
9911         if (is_simple_const(RHS(ins, 0))) {
9912                 ulong_t val;
9913                 ulong_t mask;
9914                 long_t sval;
9915                 val = read_const(state, ins, RHS(ins, 0));
9916                 mask = 1;
9917                 mask <<= ins->u.bitfield.size;
9918                 mask -= 1;
9919                 val >>= ins->u.bitfield.offset;
9920                 val &= mask;
9921                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9922                 sval = val;
9923                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9924                 mkconst(state, ins, sval);
9925         }
9926 }
9927
9928 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9929 {
9930         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9931                 ulong_t targ, val;
9932                 ulong_t mask;
9933                 targ = read_const(state, ins, RHS(ins, 0));
9934                 val  = read_const(state, ins, RHS(ins, 1));
9935                 mask = 1;
9936                 mask <<= ins->u.bitfield.size;
9937                 mask -= 1;
9938                 mask <<= ins->u.bitfield.offset;
9939                 targ &= ~mask;
9940                 val <<= ins->u.bitfield.offset;
9941                 val &= mask;
9942                 targ |= val;
9943                 mkconst(state, ins, targ);
9944         }
9945 }
9946
9947 static void simplify_copy(struct compile_state *state, struct triple *ins)
9948 {
9949         struct triple *right;
9950         right = RHS(ins, 0);
9951         if (is_subset_type(ins->type, right->type)) {
9952                 ins->type = right->type;
9953         }
9954         if (equiv_types(ins->type, right->type)) {
9955                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9956         } else {
9957                 if (ins->op == OP_COPY) {
9958                         internal_error(state, ins, "type mismatch on copy");
9959                 }
9960         }
9961         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9962                 struct triple *sdecl;
9963                 ulong_t offset;
9964                 sdecl  = MISC(right, 0);
9965                 offset = right->u.cval;
9966                 mkaddr_const(state, ins, sdecl, offset);
9967         }
9968         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
9969                 switch(right->op) {
9970                 case OP_INTCONST:
9971                 {
9972                         ulong_t left;
9973                         left = read_const(state, ins, right);
9974                         /* Ensure I have not overflowed the destination. */
9975                         if (size_of(state, right->type) > size_of(state, ins->type)) {
9976                                 ulong_t mask;
9977                                 mask = 1;
9978                                 mask <<= size_of(state, ins->type);
9979                                 mask -= 1;
9980                                 left &= mask;
9981                         }
9982                         /* Ensure I am properly sign extended */
9983                         if (size_of(state, right->type) < size_of(state, ins->type) &&
9984                                 is_signed(right->type)) {
9985                                 long_t val;
9986                                 int shift;
9987                                 shift = SIZEOF_LONG - size_of(state, right->type);
9988                                 val = left;
9989                                 val <<= shift;
9990                                 val >>= shift;
9991                                 left = val;
9992                         }
9993                         mkconst(state, ins, left);
9994                         break;
9995                 }
9996                 default:
9997                         internal_error(state, ins, "uknown constant");
9998                         break;
9999                 }
10000         }
10001 }
10002
10003 static int phi_present(struct block *block)
10004 {
10005         struct triple *ptr;
10006         if (!block) {
10007                 return 0;
10008         }
10009         ptr = block->first;
10010         do {
10011                 if (ptr->op == OP_PHI) {
10012                         return 1;
10013                 }
10014                 ptr = ptr->next;
10015         } while(ptr != block->last);
10016         return 0;
10017 }
10018
10019 static int phi_dependency(struct block *block)
10020 {
10021         /* A block has a phi dependency if a phi function
10022          * depends on that block to exist, and makes a block
10023          * that is otherwise useless unsafe to remove.
10024          */
10025         if (block) {
10026                 struct block_set *edge;
10027                 for(edge = block->edges; edge; edge = edge->next) {
10028                         if (phi_present(edge->member)) {
10029                                 return 1;
10030                         }
10031                 }
10032         }
10033         return 0;
10034 }
10035
10036 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
10037 {
10038         struct triple *targ;
10039         targ = TARG(ins, 0);
10040         /* During scc_transform temporary triples are allocated that
10041          * loop back onto themselves. If I see one don't advance the
10042          * target.
10043          */
10044         while(triple_is_structural(state, targ) && 
10045                 (targ->next != targ) && (targ->next != state->first)) {
10046                 targ = targ->next;
10047         }
10048         return targ;
10049 }
10050
10051
10052 static void simplify_branch(struct compile_state *state, struct triple *ins)
10053 {
10054         int simplified, loops;
10055         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
10056                 internal_error(state, ins, "not branch");
10057         }
10058         if (ins->use != 0) {
10059                 internal_error(state, ins, "branch use");
10060         }
10061         /* The challenge here with simplify branch is that I need to 
10062          * make modifications to the control flow graph as well
10063          * as to the branch instruction itself.  That is handled
10064          * by rebuilding the basic blocks after simplify all is called.
10065          */
10066
10067         /* If we have a branch to an unconditional branch update
10068          * our target.  But watch out for dependencies from phi
10069          * functions.
10070          * Also only do this a limited number of times so
10071          * we don't get into an infinite loop.
10072          */
10073         loops = 0;
10074         do {
10075                 struct triple *targ;
10076                 simplified = 0;
10077                 targ = branch_target(state, ins);
10078                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
10079                         !phi_dependency(targ->u.block))
10080                 {
10081                         unuse_triple(TARG(ins, 0), ins);
10082                         TARG(ins, 0) = TARG(targ, 0);
10083                         use_triple(TARG(ins, 0), ins);
10084                         simplified = 1;
10085                 }
10086         } while(simplified && (++loops < 20));
10087
10088         /* If we have a conditional branch with a constant condition
10089          * make it an unconditional branch.
10090          */
10091         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
10092                 struct triple *targ;
10093                 ulong_t value;
10094                 value = read_const(state, ins, RHS(ins, 0));
10095                 unuse_triple(RHS(ins, 0), ins);
10096                 targ = TARG(ins, 0);
10097                 ins->rhs  = 0;
10098                 ins->targ = 1;
10099                 ins->op = OP_BRANCH;
10100                 if (value) {
10101                         unuse_triple(ins->next, ins);
10102                         TARG(ins, 0) = targ;
10103                 }
10104                 else {
10105                         unuse_triple(targ, ins);
10106                         TARG(ins, 0) = ins->next;
10107                 }
10108         }
10109
10110         /* If we have a branch to the next instruction,
10111          * make it a noop.
10112          */
10113         if (TARG(ins, 0) == ins->next) {
10114                 unuse_triple(TARG(ins, 0), ins);
10115                 if (ins->op == OP_CBRANCH) {
10116                         unuse_triple(RHS(ins, 0), ins);
10117                         unuse_triple(ins->next, ins);
10118                 }
10119                 ins->lhs = 0;
10120                 ins->rhs = 0;
10121                 ins->misc = 0;
10122                 ins->targ = 0;
10123                 ins->op = OP_NOOP;
10124                 if (ins->use) {
10125                         internal_error(state, ins, "noop use != 0");
10126                 }
10127         }
10128 }
10129
10130 static void simplify_label(struct compile_state *state, struct triple *ins)
10131 {
10132         /* Ignore volatile labels */
10133         if (!triple_is_pure(state, ins, ins->id)) {
10134                 return;
10135         }
10136         if (ins->use == 0) {
10137                 ins->op = OP_NOOP;
10138         }
10139         else if (ins->prev->op == OP_LABEL) {
10140                 /* In general it is not safe to merge one label that
10141                  * imediately follows another.  The problem is that the empty
10142                  * looking block may have phi functions that depend on it.
10143                  */
10144                 if (!phi_dependency(ins->prev->u.block)) {
10145                         struct triple_set *user, *next;
10146                         ins->op = OP_NOOP;
10147                         for(user = ins->use; user; user = next) {
10148                                 struct triple *use, **expr;
10149                                 next = user->next;
10150                                 use = user->member;
10151                                 expr = triple_targ(state, use, 0);
10152                                 for(;expr; expr = triple_targ(state, use, expr)) {
10153                                         if (*expr == ins) {
10154                                                 *expr = ins->prev;
10155                                                 unuse_triple(ins, use);
10156                                                 use_triple(ins->prev, use);
10157                                         }
10158                                         
10159                                 }
10160                         }
10161                         if (ins->use) {
10162                                 internal_error(state, ins, "noop use != 0");
10163                         }
10164                 }
10165         }
10166 }
10167
10168 static void simplify_phi(struct compile_state *state, struct triple *ins)
10169 {
10170         struct triple **slot;
10171         struct triple *value;
10172         int zrhs, i;
10173         ulong_t cvalue;
10174         slot = &RHS(ins, 0);
10175         zrhs = ins->rhs;
10176         if (zrhs == 0) {
10177                 return;
10178         }
10179         /* See if all of the rhs members of a phi have the same value */
10180         if (slot[0] && is_simple_const(slot[0])) {
10181                 cvalue = read_const(state, ins, slot[0]);
10182                 for(i = 1; i < zrhs; i++) {
10183                         if (    !slot[i] ||
10184                                 !is_simple_const(slot[i]) ||
10185                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10186                                 (cvalue != read_const(state, ins, slot[i]))) {
10187                                 break;
10188                         }
10189                 }
10190                 if (i == zrhs) {
10191                         mkconst(state, ins, cvalue);
10192                         return;
10193                 }
10194         }
10195         
10196         /* See if all of rhs members of a phi are the same */
10197         value = slot[0];
10198         for(i = 1; i < zrhs; i++) {
10199                 if (slot[i] != value) {
10200                         break;
10201                 }
10202         }
10203         if (i == zrhs) {
10204                 /* If the phi has a single value just copy it */
10205                 if (!is_subset_type(ins->type, value->type)) {
10206                         internal_error(state, ins, "bad input type to phi");
10207                 }
10208                 /* Make the types match */
10209                 if (!equiv_types(ins->type, value->type)) {
10210                         ins->type = value->type;
10211                 }
10212                 /* Now make the actual copy */
10213                 mkcopy(state, ins, value);
10214                 return;
10215         }
10216 }
10217
10218
10219 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10220 {
10221         if (is_simple_const(RHS(ins, 0))) {
10222                 ulong_t left;
10223                 left = read_const(state, ins, RHS(ins, 0));
10224                 mkconst(state, ins, bsf(left));
10225         }
10226 }
10227
10228 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10229 {
10230         if (is_simple_const(RHS(ins, 0))) {
10231                 ulong_t left;
10232                 left = read_const(state, ins, RHS(ins, 0));
10233                 mkconst(state, ins, bsr(left));
10234         }
10235 }
10236
10237
10238 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10239 static const struct simplify_table {
10240         simplify_t func;
10241         unsigned long flag;
10242 } table_simplify[] = {
10243 #define simplify_sdivt    simplify_noop
10244 #define simplify_udivt    simplify_noop
10245 #define simplify_piece    simplify_noop
10246
10247 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10248 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10249 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10250 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10251 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10252 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10253 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10254 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10255 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10256 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10257 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10258 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10259 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10260 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10261 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10262 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10263 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10264 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10265 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10266
10267 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10268 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10269 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10270 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10271 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10272 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10273 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10274 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10275 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10276 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10277 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10278 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10279
10280 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10281 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10282
10283 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10284 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10285 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10286
10287 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10288
10289 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10290 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10291 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10292 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10293
10294 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10295 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10296 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10297 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10298 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10299 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10300
10301 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10302 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10303
10304 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10305 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10306 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10307 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10308 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10309 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10310 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10311 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10312 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10313
10314 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10315 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10316 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10317 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10318 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10319 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10320 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10321 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10322 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10323 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10324 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10325 };
10326
10327 static inline void debug_simplify(struct compile_state *state, 
10328         simplify_t do_simplify, struct triple *ins)
10329 {
10330 #if DEBUG_SIMPLIFY_HIRES
10331                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10332                         /* High resolution debugging mode */
10333                         fprintf(state->dbgout, "simplifing: ");
10334                         display_triple(state->dbgout, ins);
10335                 }
10336 #endif
10337                 do_simplify(state, ins);
10338 #if DEBUG_SIMPLIFY_HIRES
10339                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10340                         /* High resolution debugging mode */
10341                         fprintf(state->dbgout, "simplified: ");
10342                         display_triple(state->dbgout, ins);
10343                 }
10344 #endif
10345 }
10346 static void simplify(struct compile_state *state, struct triple *ins)
10347 {
10348         int op;
10349         simplify_t do_simplify;
10350         if (ins == &unknown_triple) {
10351                 internal_error(state, ins, "simplifying the unknown triple?");
10352         }
10353         do {
10354                 op = ins->op;
10355                 do_simplify = 0;
10356                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10357                         do_simplify = 0;
10358                 }
10359                 else {
10360                         do_simplify = table_simplify[op].func;
10361                 }
10362                 if (do_simplify && 
10363                         !(state->compiler->flags & table_simplify[op].flag)) {
10364                         do_simplify = simplify_noop;
10365                 }
10366                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10367                         do_simplify = simplify_noop;
10368                 }
10369         
10370                 if (!do_simplify) {
10371                         internal_error(state, ins, "cannot simplify op: %d %s",
10372                                 op, tops(op));
10373                         return;
10374                 }
10375                 debug_simplify(state, do_simplify, ins);
10376         } while(ins->op != op);
10377 }
10378
10379 static void rebuild_ssa_form(struct compile_state *state);
10380
10381 static void simplify_all(struct compile_state *state)
10382 {
10383         struct triple *ins, *first;
10384         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10385                 return;
10386         }
10387         first = state->first;
10388         ins = first->prev;
10389         do {
10390                 simplify(state, ins);
10391                 ins = ins->prev;
10392         } while(ins != first->prev);
10393         ins = first;
10394         do {
10395                 simplify(state, ins);
10396                 ins = ins->next;
10397         }while(ins != first);
10398         rebuild_ssa_form(state);
10399
10400         print_blocks(state, __func__, state->dbgout);
10401 }
10402
10403 /*
10404  * Builtins....
10405  * ============================
10406  */
10407
10408 static void register_builtin_function(struct compile_state *state,
10409         const char *name, int op, struct type *rtype, ...)
10410 {
10411         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10412         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10413         struct hash_entry *ident;
10414         struct file_state file;
10415         int parameters;
10416         int name_len;
10417         va_list args;
10418         int i;
10419
10420         /* Dummy file state to get debug handling right */
10421         memset(&file, 0, sizeof(file));
10422         file.basename = "<built-in>";
10423         file.line = 1;
10424         file.report_line = 1;
10425         file.report_name = file.basename;
10426         file.prev = state->file;
10427         state->file = &file;
10428         state->function = name;
10429
10430         /* Find the Parameter count */
10431         valid_op(state, op);
10432         parameters = table_ops[op].rhs;
10433         if (parameters < 0 ) {
10434                 internal_error(state, 0, "Invalid builtin parameter count");
10435         }
10436
10437         /* Find the function type */
10438         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10439         ftype->elements = parameters;
10440         next = &ftype->right;
10441         va_start(args, rtype);
10442         for(i = 0; i < parameters; i++) {
10443                 atype = va_arg(args, struct type *);
10444                 if (!*next) {
10445                         *next = atype;
10446                 } else {
10447                         *next = new_type(TYPE_PRODUCT, *next, atype);
10448                         next = &((*next)->right);
10449                 }
10450         }
10451         if (!*next) {
10452                 *next = &void_type;
10453         }
10454         va_end(args);
10455
10456         /* Get the initial closure type */
10457         ctype = new_type(TYPE_JOIN, &void_type, 0);
10458         ctype->elements = 1;
10459
10460         /* Get the return type */
10461         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10462         crtype->elements = 2;
10463
10464         /* Generate the needed triples */
10465         def = triple(state, OP_LIST, ftype, 0, 0);
10466         first = label(state);
10467         RHS(def, 0) = first;
10468         result = flatten(state, first, variable(state, crtype));
10469         retvar = flatten(state, first, variable(state, &void_ptr_type));
10470         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10471
10472         /* Now string them together */
10473         param = ftype->right;
10474         for(i = 0; i < parameters; i++) {
10475                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10476                         atype = param->left;
10477                 } else {
10478                         atype = param;
10479                 }
10480                 arg = flatten(state, first, variable(state, atype));
10481                 param = param->right;
10482         }
10483         work = new_triple(state, op, rtype, -1, parameters);
10484         generate_lhs_pieces(state, work);
10485         for(i = 0; i < parameters; i++) {
10486                 RHS(work, i) = read_expr(state, farg(state, def, i));
10487         }
10488         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10489                 work = write_expr(state, deref_index(state, result, 1), work);
10490         }
10491         work = flatten(state, first, work);
10492         last = flatten(state, first, label(state));
10493         ret  = flatten(state, first, ret);
10494         name_len = strlen(name);
10495         ident = lookup(state, name, name_len);
10496         ftype->type_ident = ident;
10497         symbol(state, ident, &ident->sym_ident, def, ftype);
10498         
10499         state->file = file.prev;
10500         state->function = 0;
10501         state->main_function = 0;
10502
10503         if (!state->functions) {
10504                 state->functions = def;
10505         } else {
10506                 insert_triple(state, state->functions, def);
10507         }
10508         if (state->compiler->debug & DEBUG_INLINE) {
10509                 FILE *fp = state->dbgout;
10510                 fprintf(fp, "\n");
10511                 loc(fp, state, 0);
10512                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10513                 display_func(state, fp, def);
10514                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10515         }
10516 }
10517
10518 static struct type *partial_struct(struct compile_state *state,
10519         const char *field_name, struct type *type, struct type *rest)
10520 {
10521         struct hash_entry *field_ident;
10522         struct type *result;
10523         int field_name_len;
10524
10525         field_name_len = strlen(field_name);
10526         field_ident = lookup(state, field_name, field_name_len);
10527
10528         result = clone_type(0, type);
10529         result->field_ident = field_ident;
10530
10531         if (rest) {
10532                 result = new_type(TYPE_PRODUCT, result, rest);
10533         }
10534         return result;
10535 }
10536
10537 static struct type *register_builtin_type(struct compile_state *state,
10538         const char *name, struct type *type)
10539 {
10540         struct hash_entry *ident;
10541         int name_len;
10542
10543         name_len = strlen(name);
10544         ident = lookup(state, name, name_len);
10545         
10546         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10547                 ulong_t elements = 0;
10548                 struct type *field;
10549                 type = new_type(TYPE_STRUCT, type, 0);
10550                 field = type->left;
10551                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10552                         elements++;
10553                         field = field->right;
10554                 }
10555                 elements++;
10556                 symbol(state, ident, &ident->sym_tag, 0, type);
10557                 type->type_ident = ident;
10558                 type->elements = elements;
10559         }
10560         symbol(state, ident, &ident->sym_ident, 0, type);
10561         ident->tok = TOK_TYPE_NAME;
10562         return type;
10563 }
10564
10565
10566 static void register_builtins(struct compile_state *state)
10567 {
10568         struct type *div_type, *ldiv_type;
10569         struct type *udiv_type, *uldiv_type;
10570         struct type *msr_type;
10571
10572         div_type = register_builtin_type(state, "__builtin_div_t",
10573                 partial_struct(state, "quot", &int_type,
10574                 partial_struct(state, "rem",  &int_type, 0)));
10575         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10576                 partial_struct(state, "quot", &long_type,
10577                 partial_struct(state, "rem",  &long_type, 0)));
10578         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10579                 partial_struct(state, "quot", &uint_type,
10580                 partial_struct(state, "rem",  &uint_type, 0)));
10581         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10582                 partial_struct(state, "quot", &ulong_type,
10583                 partial_struct(state, "rem",  &ulong_type, 0)));
10584
10585         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10586                 &int_type, &int_type);
10587         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10588                 &long_type, &long_type);
10589         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10590                 &uint_type, &uint_type);
10591         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10592                 &ulong_type, &ulong_type);
10593
10594         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10595                 &ushort_type);
10596         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10597                 &ushort_type);
10598         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10599                 &ushort_type);
10600
10601         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10602                 &uchar_type, &ushort_type);
10603         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10604                 &ushort_type, &ushort_type);
10605         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10606                 &uint_type, &ushort_type);
10607         
10608         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10609                 &int_type);
10610         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10611                 &int_type);
10612
10613         msr_type = register_builtin_type(state, "__builtin_msr_t",
10614                 partial_struct(state, "lo", &ulong_type,
10615                 partial_struct(state, "hi", &ulong_type, 0)));
10616
10617         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10618                 &ulong_type);
10619         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10620                 &ulong_type, &ulong_type, &ulong_type);
10621         
10622         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10623                 &void_type);
10624 }
10625
10626 static struct type *declarator(
10627         struct compile_state *state, struct type *type, 
10628         struct hash_entry **ident, int need_ident);
10629 static void decl(struct compile_state *state, struct triple *first);
10630 static struct type *specifier_qualifier_list(struct compile_state *state);
10631 static int isdecl_specifier(int tok);
10632 static struct type *decl_specifiers(struct compile_state *state);
10633 static int istype(int tok);
10634 static struct triple *expr(struct compile_state *state);
10635 static struct triple *assignment_expr(struct compile_state *state);
10636 static struct type *type_name(struct compile_state *state);
10637 static void statement(struct compile_state *state, struct triple *first);
10638
10639 static struct triple *call_expr(
10640         struct compile_state *state, struct triple *func)
10641 {
10642         struct triple *def;
10643         struct type *param, *type;
10644         ulong_t pvals, index;
10645
10646         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10647                 error(state, 0, "Called object is not a function");
10648         }
10649         if (func->op != OP_LIST) {
10650                 internal_error(state, 0, "improper function");
10651         }
10652         eat(state, TOK_LPAREN);
10653         /* Find the return type without any specifiers */
10654         type = clone_type(0, func->type->left);
10655         /* Count the number of rhs entries for OP_FCALL */
10656         param = func->type->right;
10657         pvals = 0;
10658         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10659                 pvals++;
10660                 param = param->right;
10661         }
10662         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10663                 pvals++;
10664         }
10665         def = new_triple(state, OP_FCALL, type, -1, pvals);
10666         MISC(def, 0) = func;
10667
10668         param = func->type->right;
10669         for(index = 0; index < pvals; index++) {
10670                 struct triple *val;
10671                 struct type *arg_type;
10672                 val = read_expr(state, assignment_expr(state));
10673                 arg_type = param;
10674                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10675                         arg_type = param->left;
10676                 }
10677                 write_compatible(state, arg_type, val->type);
10678                 RHS(def, index) = val;
10679                 if (index != (pvals - 1)) {
10680                         eat(state, TOK_COMMA);
10681                         param = param->right;
10682                 }
10683         }
10684         eat(state, TOK_RPAREN);
10685         return def;
10686 }
10687
10688
10689 static struct triple *character_constant(struct compile_state *state)
10690 {
10691         struct triple *def;
10692         struct token *tk;
10693         const signed char *str, *end;
10694         int c;
10695         int str_len;
10696         tk = eat(state, TOK_LIT_CHAR);
10697         str = tk->val.str + 1;
10698         str_len = tk->str_len - 2;
10699         if (str_len <= 0) {
10700                 error(state, 0, "empty character constant");
10701         }
10702         end = str + str_len;
10703         c = char_value(state, &str, end);
10704         if (str != end) {
10705                 error(state, 0, "multibyte character constant not supported");
10706         }
10707         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10708         return def;
10709 }
10710
10711 static struct triple *string_constant(struct compile_state *state)
10712 {
10713         struct triple *def;
10714         struct token *tk;
10715         struct type *type;
10716         const signed char *str, *end;
10717         signed char *buf, *ptr;
10718         int str_len;
10719
10720         buf = 0;
10721         type = new_type(TYPE_ARRAY, &char_type, 0);
10722         type->elements = 0;
10723         /* The while loop handles string concatenation */
10724         do {
10725                 tk = eat(state, TOK_LIT_STRING);
10726                 str = tk->val.str + 1;
10727                 str_len = tk->str_len - 2;
10728                 if (str_len < 0) {
10729                         error(state, 0, "negative string constant length");
10730                 }
10731                 end = str + str_len;
10732                 ptr = buf;
10733                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10734                 memcpy(buf, ptr, type->elements);
10735                 ptr = buf + type->elements;
10736                 do {
10737                         *ptr++ = char_value(state, &str, end);
10738                 } while(str < end);
10739                 type->elements = ptr - buf;
10740         } while(peek(state) == TOK_LIT_STRING);
10741         *ptr = '\0';
10742         type->elements += 1;
10743         def = triple(state, OP_BLOBCONST, type, 0, 0);
10744         def->u.blob = buf;
10745
10746         return def;
10747 }
10748
10749
10750 static struct triple *integer_constant(struct compile_state *state)
10751 {
10752         struct triple *def;
10753         unsigned long val;
10754         struct token *tk;
10755         char *end;
10756         int u, l, decimal;
10757         struct type *type;
10758
10759         tk = eat(state, TOK_LIT_INT);
10760         errno = 0;
10761         decimal = (tk->val.str[0] != '0');
10762         val = strtoul(tk->val.str, &end, 0);
10763         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10764                 error(state, 0, "Integer constant to large");
10765         }
10766         u = l = 0;
10767         if ((*end == 'u') || (*end == 'U')) {
10768                 u = 1;
10769                         end++;
10770         }
10771         if ((*end == 'l') || (*end == 'L')) {
10772                 l = 1;
10773                 end++;
10774         }
10775         if ((*end == 'u') || (*end == 'U')) {
10776                 u = 1;
10777                 end++;
10778         }
10779         if (*end) {
10780                 error(state, 0, "Junk at end of integer constant");
10781         }
10782         if (u && l)  {
10783                 type = &ulong_type;
10784         }
10785         else if (l) {
10786                 type = &long_type;
10787                 if (!decimal && (val > LONG_T_MAX)) {
10788                         type = &ulong_type;
10789                 }
10790         }
10791         else if (u) {
10792                 type = &uint_type;
10793                 if (val > UINT_T_MAX) {
10794                         type = &ulong_type;
10795                 }
10796         }
10797         else {
10798                 type = &int_type;
10799                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10800                         type = &uint_type;
10801                 }
10802                 else if (!decimal && (val > LONG_T_MAX)) {
10803                         type = &ulong_type;
10804                 }
10805                 else if (val > INT_T_MAX) {
10806                         type = &long_type;
10807                 }
10808         }
10809         def = int_const(state, type, val);
10810         return def;
10811 }
10812
10813 static struct triple *primary_expr(struct compile_state *state)
10814 {
10815         struct triple *def;
10816         int tok;
10817         tok = peek(state);
10818         switch(tok) {
10819         case TOK_IDENT:
10820         {
10821                 struct hash_entry *ident;
10822                 /* Here ident is either:
10823                  * a varable name
10824                  * a function name
10825                  */
10826                 ident = eat(state, TOK_IDENT)->ident;
10827                 if (!ident->sym_ident) {
10828                         error(state, 0, "%s undeclared", ident->name);
10829                 }
10830                 def = ident->sym_ident->def;
10831                 break;
10832         }
10833         case TOK_ENUM_CONST:
10834         {
10835                 struct hash_entry *ident;
10836                 /* Here ident is an enumeration constant */
10837                 ident = eat(state, TOK_ENUM_CONST)->ident;
10838                 if (!ident->sym_ident) {
10839                         error(state, 0, "%s undeclared", ident->name);
10840                 }
10841                 def = ident->sym_ident->def;
10842                 break;
10843         }
10844         case TOK_MIDENT:
10845         {
10846                 struct hash_entry *ident;
10847                 ident = eat(state, TOK_MIDENT)->ident;
10848                 warning(state, 0, "Replacing undefined macro: %s with 0",
10849                         ident->name);
10850                 def = int_const(state, &int_type, 0);
10851                 break;
10852         }
10853         case TOK_LPAREN:
10854                 eat(state, TOK_LPAREN);
10855                 def = expr(state);
10856                 eat(state, TOK_RPAREN);
10857                 break;
10858         case TOK_LIT_INT:
10859                 def = integer_constant(state);
10860                 break;
10861         case TOK_LIT_FLOAT:
10862                 eat(state, TOK_LIT_FLOAT);
10863                 error(state, 0, "Floating point constants not supported");
10864                 def = 0;
10865                 FINISHME();
10866                 break;
10867         case TOK_LIT_CHAR:
10868                 def = character_constant(state);
10869                 break;
10870         case TOK_LIT_STRING:
10871                 def = string_constant(state);
10872                 break;
10873         default:
10874                 def = 0;
10875                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10876         }
10877         return def;
10878 }
10879
10880 static struct triple *postfix_expr(struct compile_state *state)
10881 {
10882         struct triple *def;
10883         int postfix;
10884         def = primary_expr(state);
10885         do {
10886                 struct triple *left;
10887                 int tok;
10888                 postfix = 1;
10889                 left = def;
10890                 switch((tok = peek(state))) {
10891                 case TOK_LBRACKET:
10892                         eat(state, TOK_LBRACKET);
10893                         def = mk_subscript_expr(state, left, expr(state));
10894                         eat(state, TOK_RBRACKET);
10895                         break;
10896                 case TOK_LPAREN:
10897                         def = call_expr(state, def);
10898                         break;
10899                 case TOK_DOT:
10900                 {
10901                         struct hash_entry *field;
10902                         eat(state, TOK_DOT);
10903                         field = eat(state, TOK_IDENT)->ident;
10904                         def = deref_field(state, def, field);
10905                         break;
10906                 }
10907                 case TOK_ARROW:
10908                 {
10909                         struct hash_entry *field;
10910                         eat(state, TOK_ARROW);
10911                         field = eat(state, TOK_IDENT)->ident;
10912                         def = mk_deref_expr(state, read_expr(state, def));
10913                         def = deref_field(state, def, field);
10914                         break;
10915                 }
10916                 case TOK_PLUSPLUS:
10917                         eat(state, TOK_PLUSPLUS);
10918                         def = mk_post_inc_expr(state, left);
10919                         break;
10920                 case TOK_MINUSMINUS:
10921                         eat(state, TOK_MINUSMINUS);
10922                         def = mk_post_dec_expr(state, left);
10923                         break;
10924                 default:
10925                         postfix = 0;
10926                         break;
10927                 }
10928         } while(postfix);
10929         return def;
10930 }
10931
10932 static struct triple *cast_expr(struct compile_state *state);
10933
10934 static struct triple *unary_expr(struct compile_state *state)
10935 {
10936         struct triple *def, *right;
10937         int tok;
10938         switch((tok = peek(state))) {
10939         case TOK_PLUSPLUS:
10940                 eat(state, TOK_PLUSPLUS);
10941                 def = mk_pre_inc_expr(state, unary_expr(state));
10942                 break;
10943         case TOK_MINUSMINUS:
10944                 eat(state, TOK_MINUSMINUS);
10945                 def = mk_pre_dec_expr(state, unary_expr(state));
10946                 break;
10947         case TOK_AND:
10948                 eat(state, TOK_AND);
10949                 def = mk_addr_expr(state, cast_expr(state), 0);
10950                 break;
10951         case TOK_STAR:
10952                 eat(state, TOK_STAR);
10953                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10954                 break;
10955         case TOK_PLUS:
10956                 eat(state, TOK_PLUS);
10957                 right = read_expr(state, cast_expr(state));
10958                 arithmetic(state, right);
10959                 def = integral_promotion(state, right);
10960                 break;
10961         case TOK_MINUS:
10962                 eat(state, TOK_MINUS);
10963                 right = read_expr(state, cast_expr(state));
10964                 arithmetic(state, right);
10965                 def = integral_promotion(state, right);
10966                 def = triple(state, OP_NEG, def->type, def, 0);
10967                 break;
10968         case TOK_TILDE:
10969                 eat(state, TOK_TILDE);
10970                 right = read_expr(state, cast_expr(state));
10971                 integral(state, right);
10972                 def = integral_promotion(state, right);
10973                 def = triple(state, OP_INVERT, def->type, def, 0);
10974                 break;
10975         case TOK_BANG:
10976                 eat(state, TOK_BANG);
10977                 right = read_expr(state, cast_expr(state));
10978                 bool(state, right);
10979                 def = lfalse_expr(state, right);
10980                 break;
10981         case TOK_SIZEOF:
10982         {
10983                 struct type *type;
10984                 int tok1, tok2;
10985                 eat(state, TOK_SIZEOF);
10986                 tok1 = peek(state);
10987                 tok2 = peek2(state);
10988                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10989                         eat(state, TOK_LPAREN);
10990                         type = type_name(state);
10991                         eat(state, TOK_RPAREN);
10992                 }
10993                 else {
10994                         struct triple *expr;
10995                         expr = unary_expr(state);
10996                         type = expr->type;
10997                         release_expr(state, expr);
10998                 }
10999                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
11000                 break;
11001         }
11002         case TOK_ALIGNOF:
11003         {
11004                 struct type *type;
11005                 int tok1, tok2;
11006                 eat(state, TOK_ALIGNOF);
11007                 tok1 = peek(state);
11008                 tok2 = peek2(state);
11009                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11010                         eat(state, TOK_LPAREN);
11011                         type = type_name(state);
11012                         eat(state, TOK_RPAREN);
11013                 }
11014                 else {
11015                         struct triple *expr;
11016                         expr = unary_expr(state);
11017                         type = expr->type;
11018                         release_expr(state, expr);
11019                 }
11020                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
11021                 break;
11022         }
11023         case TOK_MDEFINED:
11024         {
11025                 /* We only come here if we are called from the preprocessor */
11026                 struct hash_entry *ident;
11027                 int parens;
11028                 eat(state, TOK_MDEFINED);
11029                 parens = 0;
11030                 if (pp_peek(state) == TOK_LPAREN) {
11031                         pp_eat(state, TOK_LPAREN);
11032                         parens = 1;
11033                 }
11034                 ident = pp_eat(state, TOK_MIDENT)->ident;
11035                 if (parens) {
11036                         eat(state, TOK_RPAREN);
11037                 }
11038                 def = int_const(state, &int_type, ident->sym_define != 0);
11039                 break;
11040         }
11041         default:
11042                 def = postfix_expr(state);
11043                 break;
11044         }
11045         return def;
11046 }
11047
11048 static struct triple *cast_expr(struct compile_state *state)
11049 {
11050         struct triple *def;
11051         int tok1, tok2;
11052         tok1 = peek(state);
11053         tok2 = peek2(state);
11054         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11055                 struct type *type;
11056                 eat(state, TOK_LPAREN);
11057                 type = type_name(state);
11058                 eat(state, TOK_RPAREN);
11059                 def = mk_cast_expr(state, type, cast_expr(state));
11060         }
11061         else {
11062                 def = unary_expr(state);
11063         }
11064         return def;
11065 }
11066
11067 static struct triple *mult_expr(struct compile_state *state)
11068 {
11069         struct triple *def;
11070         int done;
11071         def = cast_expr(state);
11072         do {
11073                 struct triple *left, *right;
11074                 struct type *result_type;
11075                 int tok, op, sign;
11076                 done = 0;
11077                 tok = peek(state);
11078                 switch(tok) {
11079                 case TOK_STAR:
11080                 case TOK_DIV:
11081                 case TOK_MOD:
11082                         left = read_expr(state, def);
11083                         arithmetic(state, left);
11084
11085                         eat(state, tok);
11086
11087                         right = read_expr(state, cast_expr(state));
11088                         arithmetic(state, right);
11089
11090                         result_type = arithmetic_result(state, left, right);
11091                         sign = is_signed(result_type);
11092                         op = -1;
11093                         switch(tok) {
11094                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
11095                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
11096                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
11097                         }
11098                         def = triple(state, op, result_type, left, right);
11099                         break;
11100                 default:
11101                         done = 1;
11102                         break;
11103                 }
11104         } while(!done);
11105         return def;
11106 }
11107
11108 static struct triple *add_expr(struct compile_state *state)
11109 {
11110         struct triple *def;
11111         int done;
11112         def = mult_expr(state);
11113         do {
11114                 done = 0;
11115                 switch( peek(state)) {
11116                 case TOK_PLUS:
11117                         eat(state, TOK_PLUS);
11118                         def = mk_add_expr(state, def, mult_expr(state));
11119                         break;
11120                 case TOK_MINUS:
11121                         eat(state, TOK_MINUS);
11122                         def = mk_sub_expr(state, def, mult_expr(state));
11123                         break;
11124                 default:
11125                         done = 1;
11126                         break;
11127                 }
11128         } while(!done);
11129         return def;
11130 }
11131
11132 static struct triple *shift_expr(struct compile_state *state)
11133 {
11134         struct triple *def;
11135         int done;
11136         def = add_expr(state);
11137         do {
11138                 struct triple *left, *right;
11139                 int tok, op;
11140                 done = 0;
11141                 switch((tok = peek(state))) {
11142                 case TOK_SL:
11143                 case TOK_SR:
11144                         left = read_expr(state, def);
11145                         integral(state, left);
11146                         left = integral_promotion(state, left);
11147
11148                         eat(state, tok);
11149
11150                         right = read_expr(state, add_expr(state));
11151                         integral(state, right);
11152                         right = integral_promotion(state, right);
11153                         
11154                         op = (tok == TOK_SL)? OP_SL : 
11155                                 is_signed(left->type)? OP_SSR: OP_USR;
11156
11157                         def = triple(state, op, left->type, left, right);
11158                         break;
11159                 default:
11160                         done = 1;
11161                         break;
11162                 }
11163         } while(!done);
11164         return def;
11165 }
11166
11167 static struct triple *relational_expr(struct compile_state *state)
11168 {
11169 #warning "Extend relational exprs to work on more than arithmetic types"
11170         struct triple *def;
11171         int done;
11172         def = shift_expr(state);
11173         do {
11174                 struct triple *left, *right;
11175                 struct type *arg_type;
11176                 int tok, op, sign;
11177                 done = 0;
11178                 switch((tok = peek(state))) {
11179                 case TOK_LESS:
11180                 case TOK_MORE:
11181                 case TOK_LESSEQ:
11182                 case TOK_MOREEQ:
11183                         left = read_expr(state, def);
11184                         arithmetic(state, left);
11185
11186                         eat(state, tok);
11187
11188                         right = read_expr(state, shift_expr(state));
11189                         arithmetic(state, right);
11190
11191                         arg_type = arithmetic_result(state, left, right);
11192                         sign = is_signed(arg_type);
11193                         op = -1;
11194                         switch(tok) {
11195                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11196                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11197                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11198                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11199                         }
11200                         def = triple(state, op, &int_type, left, right);
11201                         break;
11202                 default:
11203                         done = 1;
11204                         break;
11205                 }
11206         } while(!done);
11207         return def;
11208 }
11209
11210 static struct triple *equality_expr(struct compile_state *state)
11211 {
11212 #warning "Extend equality exprs to work on more than arithmetic types"
11213         struct triple *def;
11214         int done;
11215         def = relational_expr(state);
11216         do {
11217                 struct triple *left, *right;
11218                 int tok, op;
11219                 done = 0;
11220                 switch((tok = peek(state))) {
11221                 case TOK_EQEQ:
11222                 case TOK_NOTEQ:
11223                         left = read_expr(state, def);
11224                         arithmetic(state, left);
11225                         eat(state, tok);
11226                         right = read_expr(state, relational_expr(state));
11227                         arithmetic(state, right);
11228                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11229                         def = triple(state, op, &int_type, left, right);
11230                         break;
11231                 default:
11232                         done = 1;
11233                         break;
11234                 }
11235         } while(!done);
11236         return def;
11237 }
11238
11239 static struct triple *and_expr(struct compile_state *state)
11240 {
11241         struct triple *def;
11242         def = equality_expr(state);
11243         while(peek(state) == TOK_AND) {
11244                 struct triple *left, *right;
11245                 struct type *result_type;
11246                 left = read_expr(state, def);
11247                 integral(state, left);
11248                 eat(state, TOK_AND);
11249                 right = read_expr(state, equality_expr(state));
11250                 integral(state, right);
11251                 result_type = arithmetic_result(state, left, right);
11252                 def = triple(state, OP_AND, result_type, left, right);
11253         }
11254         return def;
11255 }
11256
11257 static struct triple *xor_expr(struct compile_state *state)
11258 {
11259         struct triple *def;
11260         def = and_expr(state);
11261         while(peek(state) == TOK_XOR) {
11262                 struct triple *left, *right;
11263                 struct type *result_type;
11264                 left = read_expr(state, def);
11265                 integral(state, left);
11266                 eat(state, TOK_XOR);
11267                 right = read_expr(state, and_expr(state));
11268                 integral(state, right);
11269                 result_type = arithmetic_result(state, left, right);
11270                 def = triple(state, OP_XOR, result_type, left, right);
11271         }
11272         return def;
11273 }
11274
11275 static struct triple *or_expr(struct compile_state *state)
11276 {
11277         struct triple *def;
11278         def = xor_expr(state);
11279         while(peek(state) == TOK_OR) {
11280                 struct triple *left, *right;
11281                 struct type *result_type;
11282                 left = read_expr(state, def);
11283                 integral(state, left);
11284                 eat(state, TOK_OR);
11285                 right = read_expr(state, xor_expr(state));
11286                 integral(state, right);
11287                 result_type = arithmetic_result(state, left, right);
11288                 def = triple(state, OP_OR, result_type, left, right);
11289         }
11290         return def;
11291 }
11292
11293 static struct triple *land_expr(struct compile_state *state)
11294 {
11295         struct triple *def;
11296         def = or_expr(state);
11297         while(peek(state) == TOK_LOGAND) {
11298                 struct triple *left, *right;
11299                 left = read_expr(state, def);
11300                 bool(state, left);
11301                 eat(state, TOK_LOGAND);
11302                 right = read_expr(state, or_expr(state));
11303                 bool(state, right);
11304
11305                 def = mkland_expr(state,
11306                         ltrue_expr(state, left),
11307                         ltrue_expr(state, right));
11308         }
11309         return def;
11310 }
11311
11312 static struct triple *lor_expr(struct compile_state *state)
11313 {
11314         struct triple *def;
11315         def = land_expr(state);
11316         while(peek(state) == TOK_LOGOR) {
11317                 struct triple *left, *right;
11318                 left = read_expr(state, def);
11319                 bool(state, left);
11320                 eat(state, TOK_LOGOR);
11321                 right = read_expr(state, land_expr(state));
11322                 bool(state, right);
11323
11324                 def = mklor_expr(state, 
11325                         ltrue_expr(state, left),
11326                         ltrue_expr(state, right));
11327         }
11328         return def;
11329 }
11330
11331 static struct triple *conditional_expr(struct compile_state *state)
11332 {
11333         struct triple *def;
11334         def = lor_expr(state);
11335         if (peek(state) == TOK_QUEST) {
11336                 struct triple *test, *left, *right;
11337                 bool(state, def);
11338                 test = ltrue_expr(state, read_expr(state, def));
11339                 eat(state, TOK_QUEST);
11340                 left = read_expr(state, expr(state));
11341                 eat(state, TOK_COLON);
11342                 right = read_expr(state, conditional_expr(state));
11343
11344                 def = mkcond_expr(state, test, left, right);
11345         }
11346         return def;
11347 }
11348
11349 struct cv_triple {
11350         struct triple *val;
11351         int id;
11352 };
11353
11354 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11355         struct triple *dest, struct triple *val)
11356 {
11357         if (cv[dest->id].val) {
11358                 free_triple(state, cv[dest->id].val);
11359         }
11360         cv[dest->id].val = val;
11361 }
11362 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11363         struct triple *src)
11364 {
11365         return cv[src->id].val;
11366 }
11367
11368 static struct triple *eval_const_expr(
11369         struct compile_state *state, struct triple *expr)
11370 {
11371         struct triple *def;
11372         if (is_const(expr)) {
11373                 def = expr;
11374         }
11375         else {
11376                 /* If we don't start out as a constant simplify into one */
11377                 struct triple *head, *ptr;
11378                 struct cv_triple *cv;
11379                 int i, count;
11380                 head = label(state); /* dummy initial triple */
11381                 flatten(state, head, expr);
11382                 count = 1;
11383                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11384                         count++;
11385                 }
11386                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11387                 i = 1;
11388                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11389                         cv[i].val = 0;
11390                         cv[i].id  = ptr->id;
11391                         ptr->id   = i;
11392                         i++;
11393                 }
11394                 ptr = head->next;
11395                 do {
11396                         valid_ins(state, ptr);
11397                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11398                                 internal_error(state, ptr, 
11399                                         "unexpected %s in constant expression",
11400                                         tops(ptr->op));
11401                         }
11402                         else if (ptr->op == OP_LIST) {
11403                         }
11404                         else if (triple_is_structural(state, ptr)) {
11405                                 ptr = ptr->next;
11406                         }
11407                         else if (triple_is_ubranch(state, ptr)) {
11408                                 ptr = TARG(ptr, 0);
11409                         }
11410                         else if (triple_is_cbranch(state, ptr)) {
11411                                 struct triple *cond_val;
11412                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11413                                 if (!cond_val || !is_const(cond_val) || 
11414                                         (cond_val->op != OP_INTCONST)) 
11415                                 {
11416                                         internal_error(state, ptr, "bad branch condition");
11417                                 }
11418                                 if (cond_val->u.cval == 0) {
11419                                         ptr = ptr->next;
11420                                 } else {
11421                                         ptr = TARG(ptr, 0);
11422                                 }
11423                         }
11424                         else if (triple_is_branch(state, ptr)) {
11425                                 error(state, ptr, "bad branch type in constant expression");
11426                         }
11427                         else if (ptr->op == OP_WRITE) {
11428                                 struct triple *val;
11429                                 val = get_cv(state, cv, RHS(ptr, 0));
11430                                 
11431                                 set_cv(state, cv, MISC(ptr, 0), 
11432                                         copy_triple(state, val));
11433                                 set_cv(state, cv, ptr, 
11434                                         copy_triple(state, val));
11435                                 ptr = ptr->next;
11436                         }
11437                         else if (ptr->op == OP_READ) {
11438                                 set_cv(state, cv, ptr, 
11439                                         copy_triple(state, 
11440                                                 get_cv(state, cv, RHS(ptr, 0))));
11441                                 ptr = ptr->next;
11442                         }
11443                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11444                                 struct triple *val, **rhs;
11445                                 val = copy_triple(state, ptr);
11446                                 rhs = triple_rhs(state, val, 0);
11447                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11448                                         if (!*rhs) {
11449                                                 internal_error(state, ptr, "Missing rhs");
11450                                         }
11451                                         *rhs = get_cv(state, cv, *rhs);
11452                                 }
11453                                 simplify(state, val);
11454                                 set_cv(state, cv, ptr, val);
11455                                 ptr = ptr->next;
11456                         }
11457                         else {
11458                                 error(state, ptr, "impure operation in constant expression");
11459                         }
11460                         
11461                 } while(ptr != head);
11462
11463                 /* Get the result value */
11464                 def = get_cv(state, cv, head->prev);
11465                 cv[head->prev->id].val = 0;
11466
11467                 /* Free the temporary values */
11468                 for(i = 0; i < count; i++) {
11469                         if (cv[i].val) {
11470                                 free_triple(state, cv[i].val);
11471                                 cv[i].val = 0;
11472                         }
11473                 }
11474                 xfree(cv);
11475                 /* Free the intermediate expressions */
11476                 while(head->next != head) {
11477                         release_triple(state, head->next);
11478                 }
11479                 free_triple(state, head);
11480         }
11481         if (!is_const(def)) {
11482                 error(state, expr, "Not a constant expression");
11483         }
11484         return def;
11485 }
11486
11487 static struct triple *constant_expr(struct compile_state *state)
11488 {
11489         return eval_const_expr(state, conditional_expr(state));
11490 }
11491
11492 static struct triple *assignment_expr(struct compile_state *state)
11493 {
11494         struct triple *def, *left, *right;
11495         int tok, op, sign;
11496         /* The C grammer in K&R shows assignment expressions
11497          * only taking unary expressions as input on their
11498          * left hand side.  But specifies the precedence of
11499          * assignemnt as the lowest operator except for comma.
11500          *
11501          * Allowing conditional expressions on the left hand side
11502          * of an assignement results in a grammar that accepts
11503          * a larger set of statements than standard C.   As long
11504          * as the subset of the grammar that is standard C behaves
11505          * correctly this should cause no problems.
11506          * 
11507          * For the extra token strings accepted by the grammar
11508          * none of them should produce a valid lvalue, so they
11509          * should not produce functioning programs.
11510          *
11511          * GCC has this bug as well, so surprises should be minimal.
11512          */
11513         def = conditional_expr(state);
11514         left = def;
11515         switch((tok = peek(state))) {
11516         case TOK_EQ:
11517                 lvalue(state, left);
11518                 eat(state, TOK_EQ);
11519                 def = write_expr(state, left, 
11520                         read_expr(state, assignment_expr(state)));
11521                 break;
11522         case TOK_TIMESEQ:
11523         case TOK_DIVEQ:
11524         case TOK_MODEQ:
11525                 lvalue(state, left);
11526                 arithmetic(state, left);
11527                 eat(state, tok);
11528                 right = read_expr(state, assignment_expr(state));
11529                 arithmetic(state, right);
11530
11531                 sign = is_signed(left->type);
11532                 op = -1;
11533                 switch(tok) {
11534                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11535                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11536                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11537                 }
11538                 def = write_expr(state, left,
11539                         triple(state, op, left->type, 
11540                                 read_expr(state, left), right));
11541                 break;
11542         case TOK_PLUSEQ:
11543                 lvalue(state, left);
11544                 eat(state, TOK_PLUSEQ);
11545                 def = write_expr(state, left,
11546                         mk_add_expr(state, left, assignment_expr(state)));
11547                 break;
11548         case TOK_MINUSEQ:
11549                 lvalue(state, left);
11550                 eat(state, TOK_MINUSEQ);
11551                 def = write_expr(state, left,
11552                         mk_sub_expr(state, left, assignment_expr(state)));
11553                 break;
11554         case TOK_SLEQ:
11555         case TOK_SREQ:
11556         case TOK_ANDEQ:
11557         case TOK_XOREQ:
11558         case TOK_OREQ:
11559                 lvalue(state, left);
11560                 integral(state, left);
11561                 eat(state, tok);
11562                 right = read_expr(state, assignment_expr(state));
11563                 integral(state, right);
11564                 right = integral_promotion(state, right);
11565                 sign = is_signed(left->type);
11566                 op = -1;
11567                 switch(tok) {
11568                 case TOK_SLEQ:  op = OP_SL; break;
11569                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11570                 case TOK_ANDEQ: op = OP_AND; break;
11571                 case TOK_XOREQ: op = OP_XOR; break;
11572                 case TOK_OREQ:  op = OP_OR; break;
11573                 }
11574                 def = write_expr(state, left,
11575                         triple(state, op, left->type, 
11576                                 read_expr(state, left), right));
11577                 break;
11578         }
11579         return def;
11580 }
11581
11582 static struct triple *expr(struct compile_state *state)
11583 {
11584         struct triple *def;
11585         def = assignment_expr(state);
11586         while(peek(state) == TOK_COMMA) {
11587                 eat(state, TOK_COMMA);
11588                 def = mkprog(state, def, assignment_expr(state), 0);
11589         }
11590         return def;
11591 }
11592
11593 static void expr_statement(struct compile_state *state, struct triple *first)
11594 {
11595         if (peek(state) != TOK_SEMI) {
11596                 /* lvalue conversions always apply except when certian operators
11597                  * are applied.  I apply the lvalue conversions here
11598                  * as I know no more operators will be applied.
11599                  */
11600                 flatten(state, first, lvalue_conversion(state, expr(state)));
11601         }
11602         eat(state, TOK_SEMI);
11603 }
11604
11605 static void if_statement(struct compile_state *state, struct triple *first)
11606 {
11607         struct triple *test, *jmp1, *jmp2, *middle, *end;
11608
11609         jmp1 = jmp2 = middle = 0;
11610         eat(state, TOK_IF);
11611         eat(state, TOK_LPAREN);
11612         test = expr(state);
11613         bool(state, test);
11614         /* Cleanup and invert the test */
11615         test = lfalse_expr(state, read_expr(state, test));
11616         eat(state, TOK_RPAREN);
11617         /* Generate the needed pieces */
11618         middle = label(state);
11619         jmp1 = branch(state, middle, test);
11620         /* Thread the pieces together */
11621         flatten(state, first, test);
11622         flatten(state, first, jmp1);
11623         flatten(state, first, label(state));
11624         statement(state, first);
11625         if (peek(state) == TOK_ELSE) {
11626                 eat(state, TOK_ELSE);
11627                 /* Generate the rest of the pieces */
11628                 end = label(state);
11629                 jmp2 = branch(state, end, 0);
11630                 /* Thread them together */
11631                 flatten(state, first, jmp2);
11632                 flatten(state, first, middle);
11633                 statement(state, first);
11634                 flatten(state, first, end);
11635         }
11636         else {
11637                 flatten(state, first, middle);
11638         }
11639 }
11640
11641 static void for_statement(struct compile_state *state, struct triple *first)
11642 {
11643         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11644         struct triple *label1, *label2, *label3;
11645         struct hash_entry *ident;
11646
11647         eat(state, TOK_FOR);
11648         eat(state, TOK_LPAREN);
11649         head = test = tail = jmp1 = jmp2 = 0;
11650         if (peek(state) != TOK_SEMI) {
11651                 head = expr(state);
11652         } 
11653         eat(state, TOK_SEMI);
11654         if (peek(state) != TOK_SEMI) {
11655                 test = expr(state);
11656                 bool(state, test);
11657                 test = ltrue_expr(state, read_expr(state, test));
11658         }
11659         eat(state, TOK_SEMI);
11660         if (peek(state) != TOK_RPAREN) {
11661                 tail = expr(state);
11662         }
11663         eat(state, TOK_RPAREN);
11664         /* Generate the needed pieces */
11665         label1 = label(state);
11666         label2 = label(state);
11667         label3 = label(state);
11668         if (test) {
11669                 jmp1 = branch(state, label3, 0);
11670                 jmp2 = branch(state, label1, test);
11671         }
11672         else {
11673                 jmp2 = branch(state, label1, 0);
11674         }
11675         end = label(state);
11676         /* Remember where break and continue go */
11677         start_scope(state);
11678         ident = state->i_break;
11679         symbol(state, ident, &ident->sym_ident, end, end->type);
11680         ident = state->i_continue;
11681         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11682         /* Now include the body */
11683         flatten(state, first, head);
11684         flatten(state, first, jmp1);
11685         flatten(state, first, label1);
11686         statement(state, first);
11687         flatten(state, first, label2);
11688         flatten(state, first, tail);
11689         flatten(state, first, label3);
11690         flatten(state, first, test);
11691         flatten(state, first, jmp2);
11692         flatten(state, first, end);
11693         /* Cleanup the break/continue scope */
11694         end_scope(state);
11695 }
11696
11697 static void while_statement(struct compile_state *state, struct triple *first)
11698 {
11699         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11700         struct hash_entry *ident;
11701         eat(state, TOK_WHILE);
11702         eat(state, TOK_LPAREN);
11703         test = expr(state);
11704         bool(state, test);
11705         test = ltrue_expr(state, read_expr(state, test));
11706         eat(state, TOK_RPAREN);
11707         /* Generate the needed pieces */
11708         label1 = label(state);
11709         label2 = label(state);
11710         jmp1 = branch(state, label2, 0);
11711         jmp2 = branch(state, label1, test);
11712         end = label(state);
11713         /* Remember where break and continue go */
11714         start_scope(state);
11715         ident = state->i_break;
11716         symbol(state, ident, &ident->sym_ident, end, end->type);
11717         ident = state->i_continue;
11718         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11719         /* Thread them together */
11720         flatten(state, first, jmp1);
11721         flatten(state, first, label1);
11722         statement(state, first);
11723         flatten(state, first, label2);
11724         flatten(state, first, test);
11725         flatten(state, first, jmp2);
11726         flatten(state, first, end);
11727         /* Cleanup the break/continue scope */
11728         end_scope(state);
11729 }
11730
11731 static void do_statement(struct compile_state *state, struct triple *first)
11732 {
11733         struct triple *label1, *label2, *test, *end;
11734         struct hash_entry *ident;
11735         eat(state, TOK_DO);
11736         /* Generate the needed pieces */
11737         label1 = label(state);
11738         label2 = label(state);
11739         end = label(state);
11740         /* Remember where break and continue go */
11741         start_scope(state);
11742         ident = state->i_break;
11743         symbol(state, ident, &ident->sym_ident, end, end->type);
11744         ident = state->i_continue;
11745         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11746         /* Now include the body */
11747         flatten(state, first, label1);
11748         statement(state, first);
11749         /* Cleanup the break/continue scope */
11750         end_scope(state);
11751         /* Eat the rest of the loop */
11752         eat(state, TOK_WHILE);
11753         eat(state, TOK_LPAREN);
11754         test = read_expr(state, expr(state));
11755         bool(state, test);
11756         eat(state, TOK_RPAREN);
11757         eat(state, TOK_SEMI);
11758         /* Thread the pieces together */
11759         test = ltrue_expr(state, test);
11760         flatten(state, first, label2);
11761         flatten(state, first, test);
11762         flatten(state, first, branch(state, label1, test));
11763         flatten(state, first, end);
11764 }
11765
11766
11767 static void return_statement(struct compile_state *state, struct triple *first)
11768 {
11769         struct triple *jmp, *mv, *dest, *var, *val;
11770         int last;
11771         eat(state, TOK_RETURN);
11772
11773 #warning "FIXME implement a more general excess branch elimination"
11774         val = 0;
11775         /* If we have a return value do some more work */
11776         if (peek(state) != TOK_SEMI) {
11777                 val = read_expr(state, expr(state));
11778         }
11779         eat(state, TOK_SEMI);
11780
11781         /* See if this last statement in a function */
11782         last = ((peek(state) == TOK_RBRACE) && 
11783                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11784
11785         /* Find the return variable */
11786         var = fresult(state, state->main_function);
11787
11788         /* Find the return destination */
11789         dest = state->i_return->sym_ident->def;
11790         mv = jmp = 0;
11791         /* If needed generate a jump instruction */
11792         if (!last) {
11793                 jmp = branch(state, dest, 0);
11794         }
11795         /* If needed generate an assignment instruction */
11796         if (val) {
11797                 mv = write_expr(state, deref_index(state, var, 1), val);
11798         }
11799         /* Now put the code together */
11800         if (mv) {
11801                 flatten(state, first, mv);
11802                 flatten(state, first, jmp);
11803         }
11804         else if (jmp) {
11805                 flatten(state, first, jmp);
11806         }
11807 }
11808
11809 static void break_statement(struct compile_state *state, struct triple *first)
11810 {
11811         struct triple *dest;
11812         eat(state, TOK_BREAK);
11813         eat(state, TOK_SEMI);
11814         if (!state->i_break->sym_ident) {
11815                 error(state, 0, "break statement not within loop or switch");
11816         }
11817         dest = state->i_break->sym_ident->def;
11818         flatten(state, first, branch(state, dest, 0));
11819 }
11820
11821 static void continue_statement(struct compile_state *state, struct triple *first)
11822 {
11823         struct triple *dest;
11824         eat(state, TOK_CONTINUE);
11825         eat(state, TOK_SEMI);
11826         if (!state->i_continue->sym_ident) {
11827                 error(state, 0, "continue statement outside of a loop");
11828         }
11829         dest = state->i_continue->sym_ident->def;
11830         flatten(state, first, branch(state, dest, 0));
11831 }
11832
11833 static void goto_statement(struct compile_state *state, struct triple *first)
11834 {
11835         struct hash_entry *ident;
11836         eat(state, TOK_GOTO);
11837         ident = eat(state, TOK_IDENT)->ident;
11838         if (!ident->sym_label) {
11839                 /* If this is a forward branch allocate the label now,
11840                  * it will be flattend in the appropriate location later.
11841                  */
11842                 struct triple *ins;
11843                 ins = label(state);
11844                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11845         }
11846         eat(state, TOK_SEMI);
11847
11848         flatten(state, first, branch(state, ident->sym_label->def, 0));
11849 }
11850
11851 static void labeled_statement(struct compile_state *state, struct triple *first)
11852 {
11853         struct triple *ins;
11854         struct hash_entry *ident;
11855
11856         ident = eat(state, TOK_IDENT)->ident;
11857         if (ident->sym_label && ident->sym_label->def) {
11858                 ins = ident->sym_label->def;
11859                 put_occurance(ins->occurance);
11860                 ins->occurance = new_occurance(state);
11861         }
11862         else {
11863                 ins = label(state);
11864                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11865         }
11866         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11867                 error(state, 0, "label %s already defined", ident->name);
11868         }
11869         flatten(state, first, ins);
11870
11871         eat(state, TOK_COLON);
11872         statement(state, first);
11873 }
11874
11875 static void switch_statement(struct compile_state *state, struct triple *first)
11876 {
11877         struct triple *value, *top, *end, *dbranch;
11878         struct hash_entry *ident;
11879
11880         /* See if we have a valid switch statement */
11881         eat(state, TOK_SWITCH);
11882         eat(state, TOK_LPAREN);
11883         value = expr(state);
11884         integral(state, value);
11885         value = read_expr(state, value);
11886         eat(state, TOK_RPAREN);
11887         /* Generate the needed pieces */
11888         top = label(state);
11889         end = label(state);
11890         dbranch = branch(state, end, 0);
11891         /* Remember where case branches and break goes */
11892         start_scope(state);
11893         ident = state->i_switch;
11894         symbol(state, ident, &ident->sym_ident, value, value->type);
11895         ident = state->i_case;
11896         symbol(state, ident, &ident->sym_ident, top, top->type);
11897         ident = state->i_break;
11898         symbol(state, ident, &ident->sym_ident, end, end->type);
11899         ident = state->i_default;
11900         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11901         /* Thread them together */
11902         flatten(state, first, value);
11903         flatten(state, first, top);
11904         flatten(state, first, dbranch);
11905         statement(state, first);
11906         flatten(state, first, end);
11907         /* Cleanup the switch scope */
11908         end_scope(state);
11909 }
11910
11911 static void case_statement(struct compile_state *state, struct triple *first)
11912 {
11913         struct triple *cvalue, *dest, *test, *jmp;
11914         struct triple *ptr, *value, *top, *dbranch;
11915
11916         /* See if w have a valid case statement */
11917         eat(state, TOK_CASE);
11918         cvalue = constant_expr(state);
11919         integral(state, cvalue);
11920         if (cvalue->op != OP_INTCONST) {
11921                 error(state, 0, "integer constant expected");
11922         }
11923         eat(state, TOK_COLON);
11924         if (!state->i_case->sym_ident) {
11925                 error(state, 0, "case statement not within a switch");
11926         }
11927
11928         /* Lookup the interesting pieces */
11929         top = state->i_case->sym_ident->def;
11930         value = state->i_switch->sym_ident->def;
11931         dbranch = state->i_default->sym_ident->def;
11932
11933         /* See if this case label has already been used */
11934         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11935                 if (ptr->op != OP_EQ) {
11936                         continue;
11937                 }
11938                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11939                         error(state, 0, "duplicate case %d statement",
11940                                 cvalue->u.cval);
11941                 }
11942         }
11943         /* Generate the needed pieces */
11944         dest = label(state);
11945         test = triple(state, OP_EQ, &int_type, value, cvalue);
11946         jmp = branch(state, dest, test);
11947         /* Thread the pieces together */
11948         flatten(state, dbranch, test);
11949         flatten(state, dbranch, jmp);
11950         flatten(state, dbranch, label(state));
11951         flatten(state, first, dest);
11952         statement(state, first);
11953 }
11954
11955 static void default_statement(struct compile_state *state, struct triple *first)
11956 {
11957         struct triple *dest;
11958         struct triple *dbranch, *end;
11959
11960         /* See if we have a valid default statement */
11961         eat(state, TOK_DEFAULT);
11962         eat(state, TOK_COLON);
11963
11964         if (!state->i_case->sym_ident) {
11965                 error(state, 0, "default statement not within a switch");
11966         }
11967
11968         /* Lookup the interesting pieces */
11969         dbranch = state->i_default->sym_ident->def;
11970         end = state->i_break->sym_ident->def;
11971
11972         /* See if a default statement has already happened */
11973         if (TARG(dbranch, 0) != end) {
11974                 error(state, 0, "duplicate default statement");
11975         }
11976
11977         /* Generate the needed pieces */
11978         dest = label(state);
11979
11980         /* Blame the branch on the default statement */
11981         put_occurance(dbranch->occurance);
11982         dbranch->occurance = new_occurance(state);
11983
11984         /* Thread the pieces together */
11985         TARG(dbranch, 0) = dest;
11986         use_triple(dest, dbranch);
11987         flatten(state, first, dest);
11988         statement(state, first);
11989 }
11990
11991 static void asm_statement(struct compile_state *state, struct triple *first)
11992 {
11993         struct asm_info *info;
11994         struct {
11995                 struct triple *constraint;
11996                 struct triple *expr;
11997         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
11998         struct triple *def, *asm_str;
11999         int out, in, clobbers, more, colons, i;
12000         int flags;
12001
12002         flags = 0;
12003         eat(state, TOK_ASM);
12004         /* For now ignore the qualifiers */
12005         switch(peek(state)) {
12006         case TOK_CONST:
12007                 eat(state, TOK_CONST);
12008                 break;
12009         case TOK_VOLATILE:
12010                 eat(state, TOK_VOLATILE);
12011                 flags |= TRIPLE_FLAG_VOLATILE;
12012                 break;
12013         }
12014         eat(state, TOK_LPAREN);
12015         asm_str = string_constant(state);
12016
12017         colons = 0;
12018         out = in = clobbers = 0;
12019         /* Outputs */
12020         if ((colons == 0) && (peek(state) == TOK_COLON)) {
12021                 eat(state, TOK_COLON);
12022                 colons++;
12023                 more = (peek(state) == TOK_LIT_STRING);
12024                 while(more) {
12025                         struct triple *var;
12026                         struct triple *constraint;
12027                         char *str;
12028                         more = 0;
12029                         if (out > MAX_LHS) {
12030                                 error(state, 0, "Maximum output count exceeded.");
12031                         }
12032                         constraint = string_constant(state);
12033                         str = constraint->u.blob;
12034                         if (str[0] != '=') {
12035                                 error(state, 0, "Output constraint does not start with =");
12036                         }
12037                         constraint->u.blob = str + 1;
12038                         eat(state, TOK_LPAREN);
12039                         var = conditional_expr(state);
12040                         eat(state, TOK_RPAREN);
12041
12042                         lvalue(state, var);
12043                         out_param[out].constraint = constraint;
12044                         out_param[out].expr       = var;
12045                         if (peek(state) == TOK_COMMA) {
12046                                 eat(state, TOK_COMMA);
12047                                 more = 1;
12048                         }
12049                         out++;
12050                 }
12051         }
12052         /* Inputs */
12053         if ((colons == 1) && (peek(state) == TOK_COLON)) {
12054                 eat(state, TOK_COLON);
12055                 colons++;
12056                 more = (peek(state) == TOK_LIT_STRING);
12057                 while(more) {
12058                         struct triple *val;
12059                         struct triple *constraint;
12060                         char *str;
12061                         more = 0;
12062                         if (in > MAX_RHS) {
12063                                 error(state, 0, "Maximum input count exceeded.");
12064                         }
12065                         constraint = string_constant(state);
12066                         str = constraint->u.blob;
12067                         if (digitp(str[0] && str[1] == '\0')) {
12068                                 int val;
12069                                 val = digval(str[0]);
12070                                 if ((val < 0) || (val >= out)) {
12071                                         error(state, 0, "Invalid input constraint %d", val);
12072                                 }
12073                         }
12074                         eat(state, TOK_LPAREN);
12075                         val = conditional_expr(state);
12076                         eat(state, TOK_RPAREN);
12077
12078                         in_param[in].constraint = constraint;
12079                         in_param[in].expr       = val;
12080                         if (peek(state) == TOK_COMMA) {
12081                                 eat(state, TOK_COMMA);
12082                                 more = 1;
12083                         }
12084                         in++;
12085                 }
12086         }
12087
12088         /* Clobber */
12089         if ((colons == 2) && (peek(state) == TOK_COLON)) {
12090                 eat(state, TOK_COLON);
12091                 colons++;
12092                 more = (peek(state) == TOK_LIT_STRING);
12093                 while(more) {
12094                         struct triple *clobber;
12095                         more = 0;
12096                         if ((clobbers + out) > MAX_LHS) {
12097                                 error(state, 0, "Maximum clobber limit exceeded.");
12098                         }
12099                         clobber = string_constant(state);
12100
12101                         clob_param[clobbers].constraint = clobber;
12102                         if (peek(state) == TOK_COMMA) {
12103                                 eat(state, TOK_COMMA);
12104                                 more = 1;
12105                         }
12106                         clobbers++;
12107                 }
12108         }
12109         eat(state, TOK_RPAREN);
12110         eat(state, TOK_SEMI);
12111
12112
12113         info = xcmalloc(sizeof(*info), "asm_info");
12114         info->str = asm_str->u.blob;
12115         free_triple(state, asm_str);
12116
12117         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
12118         def->u.ainfo = info;
12119         def->id |= flags;
12120
12121         /* Find the register constraints */
12122         for(i = 0; i < out; i++) {
12123                 struct triple *constraint;
12124                 constraint = out_param[i].constraint;
12125                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
12126                         out_param[i].expr->type, constraint->u.blob);
12127                 free_triple(state, constraint);
12128         }
12129         for(; i - out < clobbers; i++) {
12130                 struct triple *constraint;
12131                 constraint = clob_param[i - out].constraint;
12132                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
12133                 free_triple(state, constraint);
12134         }
12135         for(i = 0; i < in; i++) {
12136                 struct triple *constraint;
12137                 const char *str;
12138                 constraint = in_param[i].constraint;
12139                 str = constraint->u.blob;
12140                 if (digitp(str[0]) && str[1] == '\0') {
12141                         struct reg_info cinfo;
12142                         int val;
12143                         val = digval(str[0]);
12144                         cinfo.reg = info->tmpl.lhs[val].reg;
12145                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12146                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12147                         if (cinfo.reg == REG_UNSET) {
12148                                 cinfo.reg = REG_VIRT0 + val;
12149                         }
12150                         if (cinfo.regcm == 0) {
12151                                 error(state, 0, "No registers for %d", val);
12152                         }
12153                         info->tmpl.lhs[val] = cinfo;
12154                         info->tmpl.rhs[i]   = cinfo;
12155                                 
12156                 } else {
12157                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12158                                 in_param[i].expr->type, str);
12159                 }
12160                 free_triple(state, constraint);
12161         }
12162
12163         /* Now build the helper expressions */
12164         for(i = 0; i < in; i++) {
12165                 RHS(def, i) = read_expr(state, in_param[i].expr);
12166         }
12167         flatten(state, first, def);
12168         for(i = 0; i < (out + clobbers); i++) {
12169                 struct type *type;
12170                 struct triple *piece;
12171                 if (i < out) {
12172                         type = out_param[i].expr->type;
12173                 } else {
12174                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12175                         if (size >= SIZEOF_LONG) {
12176                                 type = &ulong_type;
12177                         } 
12178                         else if (size >= SIZEOF_INT) {
12179                                 type = &uint_type;
12180                         }
12181                         else if (size >= SIZEOF_SHORT) {
12182                                 type = &ushort_type;
12183                         }
12184                         else {
12185                                 type = &uchar_type;
12186                         }
12187                 }
12188                 piece = triple(state, OP_PIECE, type, def, 0);
12189                 piece->u.cval = i;
12190                 LHS(def, i) = piece;
12191                 flatten(state, first, piece);
12192         }
12193         /* And write the helpers to their destinations */
12194         for(i = 0; i < out; i++) {
12195                 struct triple *piece;
12196                 piece = LHS(def, i);
12197                 flatten(state, first,
12198                         write_expr(state, out_param[i].expr, piece));
12199         }
12200 }
12201
12202
12203 static int isdecl(int tok)
12204 {
12205         switch(tok) {
12206         case TOK_AUTO:
12207         case TOK_REGISTER:
12208         case TOK_STATIC:
12209         case TOK_EXTERN:
12210         case TOK_TYPEDEF:
12211         case TOK_CONST:
12212         case TOK_RESTRICT:
12213         case TOK_VOLATILE:
12214         case TOK_VOID:
12215         case TOK_CHAR:
12216         case TOK_SHORT:
12217         case TOK_INT:
12218         case TOK_LONG:
12219         case TOK_FLOAT:
12220         case TOK_DOUBLE:
12221         case TOK_SIGNED:
12222         case TOK_UNSIGNED:
12223         case TOK_STRUCT:
12224         case TOK_UNION:
12225         case TOK_ENUM:
12226         case TOK_TYPE_NAME: /* typedef name */
12227                 return 1;
12228         default:
12229                 return 0;
12230         }
12231 }
12232
12233 static void compound_statement(struct compile_state *state, struct triple *first)
12234 {
12235         eat(state, TOK_LBRACE);
12236         start_scope(state);
12237
12238         /* statement-list opt */
12239         while (peek(state) != TOK_RBRACE) {
12240                 statement(state, first);
12241         }
12242         end_scope(state);
12243         eat(state, TOK_RBRACE);
12244 }
12245
12246 static void statement(struct compile_state *state, struct triple *first)
12247 {
12248         int tok;
12249         tok = peek(state);
12250         if (tok == TOK_LBRACE) {
12251                 compound_statement(state, first);
12252         }
12253         else if (tok == TOK_IF) {
12254                 if_statement(state, first); 
12255         }
12256         else if (tok == TOK_FOR) {
12257                 for_statement(state, first);
12258         }
12259         else if (tok == TOK_WHILE) {
12260                 while_statement(state, first);
12261         }
12262         else if (tok == TOK_DO) {
12263                 do_statement(state, first);
12264         }
12265         else if (tok == TOK_RETURN) {
12266                 return_statement(state, first);
12267         }
12268         else if (tok == TOK_BREAK) {
12269                 break_statement(state, first);
12270         }
12271         else if (tok == TOK_CONTINUE) {
12272                 continue_statement(state, first);
12273         }
12274         else if (tok == TOK_GOTO) {
12275                 goto_statement(state, first);
12276         }
12277         else if (tok == TOK_SWITCH) {
12278                 switch_statement(state, first);
12279         }
12280         else if (tok == TOK_ASM) {
12281                 asm_statement(state, first);
12282         }
12283         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12284                 labeled_statement(state, first); 
12285         }
12286         else if (tok == TOK_CASE) {
12287                 case_statement(state, first);
12288         }
12289         else if (tok == TOK_DEFAULT) {
12290                 default_statement(state, first);
12291         }
12292         else if (isdecl(tok)) {
12293                 /* This handles C99 intermixing of statements and decls */
12294                 decl(state, first);
12295         }
12296         else {
12297                 expr_statement(state, first);
12298         }
12299 }
12300
12301 static struct type *param_decl(struct compile_state *state)
12302 {
12303         struct type *type;
12304         struct hash_entry *ident;
12305         /* Cheat so the declarator will know we are not global */
12306         start_scope(state); 
12307         ident = 0;
12308         type = decl_specifiers(state);
12309         type = declarator(state, type, &ident, 0);
12310         type->field_ident = ident;
12311         end_scope(state);
12312         return type;
12313 }
12314
12315 static struct type *param_type_list(struct compile_state *state, struct type *type)
12316 {
12317         struct type *ftype, **next;
12318         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12319         next = &ftype->right;
12320         ftype->elements = 1;
12321         while(peek(state) == TOK_COMMA) {
12322                 eat(state, TOK_COMMA);
12323                 if (peek(state) == TOK_DOTS) {
12324                         eat(state, TOK_DOTS);
12325                         error(state, 0, "variadic functions not supported");
12326                 }
12327                 else {
12328                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12329                         next = &((*next)->right);
12330                         ftype->elements++;
12331                 }
12332         }
12333         return ftype;
12334 }
12335
12336 static struct type *type_name(struct compile_state *state)
12337 {
12338         struct type *type;
12339         type = specifier_qualifier_list(state);
12340         /* abstract-declarator (may consume no tokens) */
12341         type = declarator(state, type, 0, 0);
12342         return type;
12343 }
12344
12345 static struct type *direct_declarator(
12346         struct compile_state *state, struct type *type, 
12347         struct hash_entry **pident, int need_ident)
12348 {
12349         struct hash_entry *ident;
12350         struct type *outer;
12351         int op;
12352         outer = 0;
12353         arrays_complete(state, type);
12354         switch(peek(state)) {
12355         case TOK_IDENT:
12356                 ident = eat(state, TOK_IDENT)->ident;
12357                 if (!ident) {
12358                         error(state, 0, "Unexpected identifier found");
12359                 }
12360                 /* The name of what we are declaring */
12361                 *pident = ident;
12362                 break;
12363         case TOK_LPAREN:
12364                 eat(state, TOK_LPAREN);
12365                 outer = declarator(state, type, pident, need_ident);
12366                 eat(state, TOK_RPAREN);
12367                 break;
12368         default:
12369                 if (need_ident) {
12370                         error(state, 0, "Identifier expected");
12371                 }
12372                 break;
12373         }
12374         do {
12375                 op = 1;
12376                 arrays_complete(state, type);
12377                 switch(peek(state)) {
12378                 case TOK_LPAREN:
12379                         eat(state, TOK_LPAREN);
12380                         type = param_type_list(state, type);
12381                         eat(state, TOK_RPAREN);
12382                         break;
12383                 case TOK_LBRACKET:
12384                 {
12385                         unsigned int qualifiers;
12386                         struct triple *value;
12387                         value = 0;
12388                         eat(state, TOK_LBRACKET);
12389                         if (peek(state) != TOK_RBRACKET) {
12390                                 value = constant_expr(state);
12391                                 integral(state, value);
12392                         }
12393                         eat(state, TOK_RBRACKET);
12394
12395                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12396                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12397                         if (value) {
12398                                 type->elements = value->u.cval;
12399                                 free_triple(state, value);
12400                         } else {
12401                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12402                                 op = 0;
12403                         }
12404                 }
12405                         break;
12406                 default:
12407                         op = 0;
12408                         break;
12409                 }
12410         } while(op);
12411         if (outer) {
12412                 struct type *inner;
12413                 arrays_complete(state, type);
12414                 FINISHME();
12415                 for(inner = outer; inner->left; inner = inner->left)
12416                         ;
12417                 inner->left = type;
12418                 type = outer;
12419         }
12420         return type;
12421 }
12422
12423 static struct type *declarator(
12424         struct compile_state *state, struct type *type, 
12425         struct hash_entry **pident, int need_ident)
12426 {
12427         while(peek(state) == TOK_STAR) {
12428                 eat(state, TOK_STAR);
12429                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12430         }
12431         type = direct_declarator(state, type, pident, need_ident);
12432         return type;
12433 }
12434
12435 static struct type *typedef_name(
12436         struct compile_state *state, unsigned int specifiers)
12437 {
12438         struct hash_entry *ident;
12439         struct type *type;
12440         ident = eat(state, TOK_TYPE_NAME)->ident;
12441         type = ident->sym_ident->type;
12442         specifiers |= type->type & QUAL_MASK;
12443         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12444                 (type->type & (STOR_MASK | QUAL_MASK))) {
12445                 type = clone_type(specifiers, type);
12446         }
12447         return type;
12448 }
12449
12450 static struct type *enum_specifier(
12451         struct compile_state *state, unsigned int spec)
12452 {
12453         struct hash_entry *ident;
12454         ulong_t base;
12455         int tok;
12456         struct type *enum_type;
12457         enum_type = 0;
12458         ident = 0;
12459         eat(state, TOK_ENUM);
12460         tok = peek(state);
12461         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12462                 ident = eat(state, tok)->ident;
12463         }
12464         base = 0;
12465         if (!ident || (peek(state) == TOK_LBRACE)) {
12466                 struct type **next;
12467                 eat(state, TOK_LBRACE);
12468                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12469                 enum_type->type_ident = ident;
12470                 next = &enum_type->right;
12471                 do {
12472                         struct hash_entry *eident;
12473                         struct triple *value;
12474                         struct type *entry;
12475                         eident = eat(state, TOK_IDENT)->ident;
12476                         if (eident->sym_ident) {
12477                                 error(state, 0, "%s already declared", 
12478                                         eident->name);
12479                         }
12480                         eident->tok = TOK_ENUM_CONST;
12481                         if (peek(state) == TOK_EQ) {
12482                                 struct triple *val;
12483                                 eat(state, TOK_EQ);
12484                                 val = constant_expr(state);
12485                                 integral(state, val);
12486                                 base = val->u.cval;
12487                         }
12488                         value = int_const(state, &int_type, base);
12489                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12490                         entry = new_type(TYPE_LIST, 0, 0);
12491                         entry->field_ident = eident;
12492                         *next = entry;
12493                         next = &entry->right;
12494                         base += 1;
12495                         if (peek(state) == TOK_COMMA) {
12496                                 eat(state, TOK_COMMA);
12497                         }
12498                 } while(peek(state) != TOK_RBRACE);
12499                 eat(state, TOK_RBRACE);
12500                 if (ident) {
12501                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12502                 }
12503         }
12504         if (ident && ident->sym_tag &&
12505                 ident->sym_tag->type &&
12506                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12507                 enum_type = clone_type(spec, ident->sym_tag->type);
12508         }
12509         else if (ident && !enum_type) {
12510                 error(state, 0, "enum %s undeclared", ident->name);
12511         }
12512         return enum_type;
12513 }
12514
12515 static struct type *struct_declarator(
12516         struct compile_state *state, struct type *type, struct hash_entry **ident)
12517 {
12518         if (peek(state) != TOK_COLON) {
12519                 type = declarator(state, type, ident, 1);
12520         }
12521         if (peek(state) == TOK_COLON) {
12522                 struct triple *value;
12523                 eat(state, TOK_COLON);
12524                 value = constant_expr(state);
12525                 if (value->op != OP_INTCONST) {
12526                         error(state, 0, "Invalid constant expression");
12527                 }
12528                 if (value->u.cval > size_of(state, type)) {
12529                         error(state, 0, "bitfield larger than base type");
12530                 }
12531                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12532                         error(state, 0, "bitfield base not an integer type");
12533                 }
12534                 type = new_type(TYPE_BITFIELD, type, 0);
12535                 type->elements = value->u.cval;
12536         }
12537         return type;
12538 }
12539
12540 static struct type *struct_or_union_specifier(
12541         struct compile_state *state, unsigned int spec)
12542 {
12543         struct type *struct_type;
12544         struct hash_entry *ident;
12545         unsigned int type_main;
12546         unsigned int type_join;
12547         int tok;
12548         struct_type = 0;
12549         ident = 0;
12550         switch(peek(state)) {
12551         case TOK_STRUCT:
12552                 eat(state, TOK_STRUCT);
12553                 type_main = TYPE_STRUCT;
12554                 type_join = TYPE_PRODUCT;
12555                 break;
12556         case TOK_UNION:
12557                 eat(state, TOK_UNION);
12558                 type_main = TYPE_UNION;
12559                 type_join = TYPE_OVERLAP;
12560                 break;
12561         default:
12562                 eat(state, TOK_STRUCT);
12563                 type_main = TYPE_STRUCT;
12564                 type_join = TYPE_PRODUCT;
12565                 break;
12566         }
12567         tok = peek(state);
12568         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12569                 ident = eat(state, tok)->ident;
12570         }
12571         if (!ident || (peek(state) == TOK_LBRACE)) {
12572                 ulong_t elements;
12573                 struct type **next;
12574                 elements = 0;
12575                 eat(state, TOK_LBRACE);
12576                 next = &struct_type;
12577                 do {
12578                         struct type *base_type;
12579                         int done;
12580                         base_type = specifier_qualifier_list(state);
12581                         do {
12582                                 struct type *type;
12583                                 struct hash_entry *fident;
12584                                 done = 1;
12585                                 type = struct_declarator(state, base_type, &fident);
12586                                 elements++;
12587                                 if (peek(state) == TOK_COMMA) {
12588                                         done = 0;
12589                                         eat(state, TOK_COMMA);
12590                                 }
12591                                 type = clone_type(0, type);
12592                                 type->field_ident = fident;
12593                                 if (*next) {
12594                                         *next = new_type(type_join, *next, type);
12595                                         next = &((*next)->right);
12596                                 } else {
12597                                         *next = type;
12598                                 }
12599                         } while(!done);
12600                         eat(state, TOK_SEMI);
12601                 } while(peek(state) != TOK_RBRACE);
12602                 eat(state, TOK_RBRACE);
12603                 struct_type = new_type(type_main | spec, struct_type, 0);
12604                 struct_type->type_ident = ident;
12605                 struct_type->elements = elements;
12606                 if (ident) {
12607                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12608                 }
12609         }
12610         if (ident && ident->sym_tag && 
12611                 ident->sym_tag->type && 
12612                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12613                 struct_type = clone_type(spec, ident->sym_tag->type);
12614         }
12615         else if (ident && !struct_type) {
12616                 error(state, 0, "%s %s undeclared", 
12617                         (type_main == TYPE_STRUCT)?"struct" : "union",
12618                         ident->name);
12619         }
12620         return struct_type;
12621 }
12622
12623 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12624 {
12625         unsigned int specifiers;
12626         switch(peek(state)) {
12627         case TOK_AUTO:
12628                 eat(state, TOK_AUTO);
12629                 specifiers = STOR_AUTO;
12630                 break;
12631         case TOK_REGISTER:
12632                 eat(state, TOK_REGISTER);
12633                 specifiers = STOR_REGISTER;
12634                 break;
12635         case TOK_STATIC:
12636                 eat(state, TOK_STATIC);
12637                 specifiers = STOR_STATIC;
12638                 break;
12639         case TOK_EXTERN:
12640                 eat(state, TOK_EXTERN);
12641                 specifiers = STOR_EXTERN;
12642                 break;
12643         case TOK_TYPEDEF:
12644                 eat(state, TOK_TYPEDEF);
12645                 specifiers = STOR_TYPEDEF;
12646                 break;
12647         default:
12648                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12649                         specifiers = STOR_LOCAL;
12650                 }
12651                 else {
12652                         specifiers = STOR_AUTO;
12653                 }
12654         }
12655         return specifiers;
12656 }
12657
12658 static unsigned int function_specifier_opt(struct compile_state *state)
12659 {
12660         /* Ignore the inline keyword */
12661         unsigned int specifiers;
12662         specifiers = 0;
12663         switch(peek(state)) {
12664         case TOK_INLINE:
12665                 eat(state, TOK_INLINE);
12666                 specifiers = STOR_INLINE;
12667         }
12668         return specifiers;
12669 }
12670
12671 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12672 {
12673         int tok = peek(state);
12674         switch(tok) {
12675         case TOK_COMMA:
12676         case TOK_LPAREN:
12677                 /* The empty attribute ignore it */
12678                 break;
12679         case TOK_IDENT:
12680         case TOK_ENUM_CONST:
12681         case TOK_TYPE_NAME:
12682         {
12683                 struct hash_entry *ident;
12684                 ident = eat(state, TOK_IDENT)->ident;
12685
12686                 if (ident == state->i_noinline) {
12687                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12688                                 error(state, 0, "both always_inline and noinline attribtes");
12689                         }
12690                         attributes |= ATTRIB_NOINLINE;
12691                 }
12692                 else if (ident == state->i_always_inline) {
12693                         if (attributes & ATTRIB_NOINLINE) {
12694                                 error(state, 0, "both noinline and always_inline attribtes");
12695                         }
12696                         attributes |= ATTRIB_ALWAYS_INLINE;
12697                 }
12698                 else {
12699                         error(state, 0, "Unknown attribute:%s", ident->name);
12700                 }
12701                 break;
12702         }
12703         default:
12704                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12705                 break;
12706         }
12707         return attributes;
12708 }
12709
12710 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12711 {
12712         type = attrib(state, type);
12713         while(peek(state) == TOK_COMMA) {
12714                 eat(state, TOK_COMMA);
12715                 type = attrib(state, type);
12716         }
12717         return type;
12718 }
12719
12720 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12721 {
12722         if (peek(state) == TOK_ATTRIBUTE) {
12723                 eat(state, TOK_ATTRIBUTE);
12724                 eat(state, TOK_LPAREN);
12725                 eat(state, TOK_LPAREN);
12726                 type = attribute_list(state, type);
12727                 eat(state, TOK_RPAREN);
12728                 eat(state, TOK_RPAREN);
12729         }
12730         return type;
12731 }
12732
12733 static unsigned int type_qualifiers(struct compile_state *state)
12734 {
12735         unsigned int specifiers;
12736         int done;
12737         done = 0;
12738         specifiers = QUAL_NONE;
12739         do {
12740                 switch(peek(state)) {
12741                 case TOK_CONST:
12742                         eat(state, TOK_CONST);
12743                         specifiers |= QUAL_CONST;
12744                         break;
12745                 case TOK_VOLATILE:
12746                         eat(state, TOK_VOLATILE);
12747                         specifiers |= QUAL_VOLATILE;
12748                         break;
12749                 case TOK_RESTRICT:
12750                         eat(state, TOK_RESTRICT);
12751                         specifiers |= QUAL_RESTRICT;
12752                         break;
12753                 default:
12754                         done = 1;
12755                         break;
12756                 }
12757         } while(!done);
12758         return specifiers;
12759 }
12760
12761 static struct type *type_specifier(
12762         struct compile_state *state, unsigned int spec)
12763 {
12764         struct type *type;
12765         int tok;
12766         type = 0;
12767         switch((tok = peek(state))) {
12768         case TOK_VOID:
12769                 eat(state, TOK_VOID);
12770                 type = new_type(TYPE_VOID | spec, 0, 0);
12771                 break;
12772         case TOK_CHAR:
12773                 eat(state, TOK_CHAR);
12774                 type = new_type(TYPE_CHAR | spec, 0, 0);
12775                 break;
12776         case TOK_SHORT:
12777                 eat(state, TOK_SHORT);
12778                 if (peek(state) == TOK_INT) {
12779                         eat(state, TOK_INT);
12780                 }
12781                 type = new_type(TYPE_SHORT | spec, 0, 0);
12782                 break;
12783         case TOK_INT:
12784                 eat(state, TOK_INT);
12785                 type = new_type(TYPE_INT | spec, 0, 0);
12786                 break;
12787         case TOK_LONG:
12788                 eat(state, TOK_LONG);
12789                 switch(peek(state)) {
12790                 case TOK_LONG:
12791                         eat(state, TOK_LONG);
12792                         error(state, 0, "long long not supported");
12793                         break;
12794                 case TOK_DOUBLE:
12795                         eat(state, TOK_DOUBLE);
12796                         error(state, 0, "long double not supported");
12797                         break;
12798                 case TOK_INT:
12799                         eat(state, TOK_INT);
12800                         type = new_type(TYPE_LONG | spec, 0, 0);
12801                         break;
12802                 default:
12803                         type = new_type(TYPE_LONG | spec, 0, 0);
12804                         break;
12805                 }
12806                 break;
12807         case TOK_FLOAT:
12808                 eat(state, TOK_FLOAT);
12809                 error(state, 0, "type float not supported");
12810                 break;
12811         case TOK_DOUBLE:
12812                 eat(state, TOK_DOUBLE);
12813                 error(state, 0, "type double not supported");
12814                 break;
12815         case TOK_SIGNED:
12816                 eat(state, TOK_SIGNED);
12817                 switch(peek(state)) {
12818                 case TOK_LONG:
12819                         eat(state, TOK_LONG);
12820                         switch(peek(state)) {
12821                         case TOK_LONG:
12822                                 eat(state, TOK_LONG);
12823                                 error(state, 0, "type long long not supported");
12824                                 break;
12825                         case TOK_INT:
12826                                 eat(state, TOK_INT);
12827                                 type = new_type(TYPE_LONG | spec, 0, 0);
12828                                 break;
12829                         default:
12830                                 type = new_type(TYPE_LONG | spec, 0, 0);
12831                                 break;
12832                         }
12833                         break;
12834                 case TOK_INT:
12835                         eat(state, TOK_INT);
12836                         type = new_type(TYPE_INT | spec, 0, 0);
12837                         break;
12838                 case TOK_SHORT:
12839                         eat(state, TOK_SHORT);
12840                         type = new_type(TYPE_SHORT | spec, 0, 0);
12841                         break;
12842                 case TOK_CHAR:
12843                         eat(state, TOK_CHAR);
12844                         type = new_type(TYPE_CHAR | spec, 0, 0);
12845                         break;
12846                 default:
12847                         type = new_type(TYPE_INT | spec, 0, 0);
12848                         break;
12849                 }
12850                 break;
12851         case TOK_UNSIGNED:
12852                 eat(state, TOK_UNSIGNED);
12853                 switch(peek(state)) {
12854                 case TOK_LONG:
12855                         eat(state, TOK_LONG);
12856                         switch(peek(state)) {
12857                         case TOK_LONG:
12858                                 eat(state, TOK_LONG);
12859                                 error(state, 0, "unsigned long long not supported");
12860                                 break;
12861                         case TOK_INT:
12862                                 eat(state, TOK_INT);
12863                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12864                                 break;
12865                         default:
12866                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12867                                 break;
12868                         }
12869                         break;
12870                 case TOK_INT:
12871                         eat(state, TOK_INT);
12872                         type = new_type(TYPE_UINT | spec, 0, 0);
12873                         break;
12874                 case TOK_SHORT:
12875                         eat(state, TOK_SHORT);
12876                         type = new_type(TYPE_USHORT | spec, 0, 0);
12877                         break;
12878                 case TOK_CHAR:
12879                         eat(state, TOK_CHAR);
12880                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12881                         break;
12882                 default:
12883                         type = new_type(TYPE_UINT | spec, 0, 0);
12884                         break;
12885                 }
12886                 break;
12887                 /* struct or union specifier */
12888         case TOK_STRUCT:
12889         case TOK_UNION:
12890                 type = struct_or_union_specifier(state, spec);
12891                 break;
12892                 /* enum-spefifier */
12893         case TOK_ENUM:
12894                 type = enum_specifier(state, spec);
12895                 break;
12896                 /* typedef name */
12897         case TOK_TYPE_NAME:
12898                 type = typedef_name(state, spec);
12899                 break;
12900         default:
12901                 error(state, 0, "bad type specifier %s", 
12902                         tokens[tok]);
12903                 break;
12904         }
12905         return type;
12906 }
12907
12908 static int istype(int tok)
12909 {
12910         switch(tok) {
12911         case TOK_CONST:
12912         case TOK_RESTRICT:
12913         case TOK_VOLATILE:
12914         case TOK_VOID:
12915         case TOK_CHAR:
12916         case TOK_SHORT:
12917         case TOK_INT:
12918         case TOK_LONG:
12919         case TOK_FLOAT:
12920         case TOK_DOUBLE:
12921         case TOK_SIGNED:
12922         case TOK_UNSIGNED:
12923         case TOK_STRUCT:
12924         case TOK_UNION:
12925         case TOK_ENUM:
12926         case TOK_TYPE_NAME:
12927                 return 1;
12928         default:
12929                 return 0;
12930         }
12931 }
12932
12933
12934 static struct type *specifier_qualifier_list(struct compile_state *state)
12935 {
12936         struct type *type;
12937         unsigned int specifiers = 0;
12938
12939         /* type qualifiers */
12940         specifiers |= type_qualifiers(state);
12941
12942         /* type specifier */
12943         type = type_specifier(state, specifiers);
12944
12945         return type;
12946 }
12947
12948 static int isdecl_specifier(int tok)
12949 {
12950         switch(tok) {
12951                 /* storage class specifier */
12952         case TOK_AUTO:
12953         case TOK_REGISTER:
12954         case TOK_STATIC:
12955         case TOK_EXTERN:
12956         case TOK_TYPEDEF:
12957                 /* type qualifier */
12958         case TOK_CONST:
12959         case TOK_RESTRICT:
12960         case TOK_VOLATILE:
12961                 /* type specifiers */
12962         case TOK_VOID:
12963         case TOK_CHAR:
12964         case TOK_SHORT:
12965         case TOK_INT:
12966         case TOK_LONG:
12967         case TOK_FLOAT:
12968         case TOK_DOUBLE:
12969         case TOK_SIGNED:
12970         case TOK_UNSIGNED:
12971                 /* struct or union specifier */
12972         case TOK_STRUCT:
12973         case TOK_UNION:
12974                 /* enum-spefifier */
12975         case TOK_ENUM:
12976                 /* typedef name */
12977         case TOK_TYPE_NAME:
12978                 /* function specifiers */
12979         case TOK_INLINE:
12980                 return 1;
12981         default:
12982                 return 0;
12983         }
12984 }
12985
12986 static struct type *decl_specifiers(struct compile_state *state)
12987 {
12988         struct type *type;
12989         unsigned int specifiers;
12990         /* I am overly restrictive in the arragement of specifiers supported.
12991          * C is overly flexible in this department it makes interpreting
12992          * the parse tree difficult.
12993          */
12994         specifiers = 0;
12995
12996         /* storage class specifier */
12997         specifiers |= storage_class_specifier_opt(state);
12998
12999         /* function-specifier */
13000         specifiers |= function_specifier_opt(state);
13001
13002         /* attributes */
13003         specifiers |= attributes_opt(state, 0);
13004
13005         /* type qualifier */
13006         specifiers |= type_qualifiers(state);
13007
13008         /* type specifier */
13009         type = type_specifier(state, specifiers);
13010         return type;
13011 }
13012
13013 struct field_info {
13014         struct type *type;
13015         size_t offset;
13016 };
13017
13018 static struct field_info designator(struct compile_state *state, struct type *type)
13019 {
13020         int tok;
13021         struct field_info info;
13022         info.offset = ~0U;
13023         info.type = 0;
13024         do {
13025                 switch(peek(state)) {
13026                 case TOK_LBRACKET:
13027                 {
13028                         struct triple *value;
13029                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
13030                                 error(state, 0, "Array designator not in array initializer");
13031                         }
13032                         eat(state, TOK_LBRACKET);
13033                         value = constant_expr(state);
13034                         eat(state, TOK_RBRACKET);
13035
13036                         info.type = type->left;
13037                         info.offset = value->u.cval * size_of(state, info.type);
13038                         break;
13039                 }
13040                 case TOK_DOT:
13041                 {
13042                         struct hash_entry *field;
13043                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
13044                                 ((type->type & TYPE_MASK) != TYPE_UNION))
13045                         {
13046                                 error(state, 0, "Struct designator not in struct initializer");
13047                         }
13048                         eat(state, TOK_DOT);
13049                         field = eat(state, TOK_IDENT)->ident;
13050                         info.offset = field_offset(state, type, field);
13051                         info.type   = field_type(state, type, field);
13052                         break;
13053                 }
13054                 default:
13055                         error(state, 0, "Invalid designator");
13056                 }
13057                 tok = peek(state);
13058         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
13059         eat(state, TOK_EQ);
13060         return info;
13061 }
13062
13063 static struct triple *initializer(
13064         struct compile_state *state, struct type *type)
13065 {
13066         struct triple *result;
13067 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
13068         if (peek(state) != TOK_LBRACE) {
13069                 result = assignment_expr(state);
13070                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13071                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13072                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13073                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13074                         (equiv_types(type->left, result->type->left))) {
13075                         type->elements = result->type->elements;
13076                 }
13077                 if (is_lvalue(state, result) && 
13078                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13079                         (type->type & TYPE_MASK) != TYPE_ARRAY)
13080                 {
13081                         result = lvalue_conversion(state, result);
13082                 }
13083                 if (!is_init_compatible(state, type, result->type)) {
13084                         error(state, 0, "Incompatible types in initializer");
13085                 }
13086                 if (!equiv_types(type, result->type)) {
13087                         result = mk_cast_expr(state, type, result);
13088                 }
13089         }
13090         else {
13091                 int comma;
13092                 size_t max_offset;
13093                 struct field_info info;
13094                 void *buf;
13095                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
13096                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
13097                         internal_error(state, 0, "unknown initializer type");
13098                 }
13099                 info.offset = 0;
13100                 info.type = type->left;
13101                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13102                         info.type = next_field(state, type, 0);
13103                 }
13104                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
13105                         max_offset = 0;
13106                 } else {
13107                         max_offset = size_of(state, type);
13108                 }
13109                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
13110                 eat(state, TOK_LBRACE);
13111                 do {
13112                         struct triple *value;
13113                         struct type *value_type;
13114                         size_t value_size;
13115                         void *dest;
13116                         int tok;
13117                         comma = 0;
13118                         tok = peek(state);
13119                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
13120                                 info = designator(state, type);
13121                         }
13122                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13123                                 (info.offset >= max_offset)) {
13124                                 error(state, 0, "element beyond bounds");
13125                         }
13126                         value_type = info.type;
13127                         value = eval_const_expr(state, initializer(state, value_type));
13128                         value_size = size_of(state, value_type);
13129                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13130                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13131                                 (max_offset <= info.offset)) {
13132                                 void *old_buf;
13133                                 size_t old_size;
13134                                 old_buf = buf;
13135                                 old_size = max_offset;
13136                                 max_offset = info.offset + value_size;
13137                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13138                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13139                                 xfree(old_buf);
13140                         }
13141                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13142 #if DEBUG_INITIALIZER
13143                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13144                                 dest - buf,
13145                                 bits_to_bytes(max_offset),
13146                                 bits_to_bytes(value_size),
13147                                 value->op);
13148 #endif
13149                         if (value->op == OP_BLOBCONST) {
13150                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13151                         }
13152                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13153 #if DEBUG_INITIALIZER
13154                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13155 #endif
13156                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13157                         }
13158                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13159                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13160                         }
13161                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13162                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13163                         }
13164                         else {
13165                                 internal_error(state, 0, "unhandled constant initializer");
13166                         }
13167                         free_triple(state, value);
13168                         if (peek(state) == TOK_COMMA) {
13169                                 eat(state, TOK_COMMA);
13170                                 comma = 1;
13171                         }
13172                         info.offset += value_size;
13173                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13174                                 info.type = next_field(state, type, info.type);
13175                                 info.offset = field_offset(state, type, 
13176                                         info.type->field_ident);
13177                         }
13178                 } while(comma && (peek(state) != TOK_RBRACE));
13179                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13180                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13181                         type->elements = max_offset / size_of(state, type->left);
13182                 }
13183                 eat(state, TOK_RBRACE);
13184                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13185                 result->u.blob = buf;
13186         }
13187         return result;
13188 }
13189
13190 static void resolve_branches(struct compile_state *state, struct triple *first)
13191 {
13192         /* Make a second pass and finish anything outstanding
13193          * with respect to branches.  The only outstanding item
13194          * is to see if there are goto to labels that have not
13195          * been defined and to error about them.
13196          */
13197         int i;
13198         struct triple *ins;
13199         /* Also error on branches that do not use their targets */
13200         ins = first;
13201         do {
13202                 if (!triple_is_ret(state, ins)) {
13203                         struct triple **expr ;
13204                         struct triple_set *set;
13205                         expr = triple_targ(state, ins, 0);
13206                         for(; expr; expr = triple_targ(state, ins, expr)) {
13207                                 struct triple *targ;
13208                                 targ = *expr;
13209                                 for(set = targ?targ->use:0; set; set = set->next) {
13210                                         if (set->member == ins) {
13211                                                 break;
13212                                         }
13213                                 }
13214                                 if (!set) {
13215                                         internal_error(state, ins, "targ not used");
13216                                 }
13217                         }
13218                 }
13219                 ins = ins->next;
13220         } while(ins != first);
13221         /* See if there are goto to labels that have not been defined */
13222         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13223                 struct hash_entry *entry;
13224                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13225                         struct triple *ins;
13226                         if (!entry->sym_label) {
13227                                 continue;
13228                         }
13229                         ins = entry->sym_label->def;
13230                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13231                                 error(state, ins, "label `%s' used but not defined",
13232                                         entry->name);
13233                         }
13234                 }
13235         }
13236 }
13237
13238 static struct triple *function_definition(
13239         struct compile_state *state, struct type *type)
13240 {
13241         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13242         struct triple *fname;
13243         struct type *fname_type;
13244         struct hash_entry *ident;
13245         struct type *param, *crtype, *ctype;
13246         int i;
13247         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13248                 error(state, 0, "Invalid function header");
13249         }
13250
13251         /* Verify the function type */
13252         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13253                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13254                 (type->right->field_ident == 0)) {
13255                 error(state, 0, "Invalid function parameters");
13256         }
13257         param = type->right;
13258         i = 0;
13259         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13260                 i++;
13261                 if (!param->left->field_ident) {
13262                         error(state, 0, "No identifier for parameter %d\n", i);
13263                 }
13264                 param = param->right;
13265         }
13266         i++;
13267         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13268                 error(state, 0, "No identifier for paramter %d\n", i);
13269         }
13270         
13271         /* Get a list of statements for this function. */
13272         def = triple(state, OP_LIST, type, 0, 0);
13273
13274         /* Start a new scope for the passed parameters */
13275         start_scope(state);
13276
13277         /* Put a label at the very start of a function */
13278         first = label(state);
13279         RHS(def, 0) = first;
13280
13281         /* Put a label at the very end of a function */
13282         end = label(state);
13283         flatten(state, first, end);
13284         /* Remember where return goes */
13285         ident = state->i_return;
13286         symbol(state, ident, &ident->sym_ident, end, end->type);
13287
13288         /* Get the initial closure type */
13289         ctype = new_type(TYPE_JOIN, &void_type, 0);
13290         ctype->elements = 1;
13291
13292         /* Add a variable for the return value */
13293         crtype = new_type(TYPE_TUPLE, 
13294                 /* Remove all type qualifiers from the return type */
13295                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13296         crtype->elements = 2;
13297         result = flatten(state, end, variable(state, crtype));
13298
13299         /* Allocate a variable for the return address */
13300         retvar = flatten(state, end, variable(state, &void_ptr_type));
13301
13302         /* Add in the return instruction */
13303         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13304         ret = flatten(state, first, ret);
13305
13306         /* Walk through the parameters and create symbol table entries
13307          * for them.
13308          */
13309         param = type->right;
13310         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13311                 ident = param->left->field_ident;
13312                 tmp = variable(state, param->left);
13313                 var_symbol(state, ident, tmp);
13314                 flatten(state, end, tmp);
13315                 param = param->right;
13316         }
13317         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13318                 /* And don't forget the last parameter */
13319                 ident = param->field_ident;
13320                 tmp = variable(state, param);
13321                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13322                 flatten(state, end, tmp);
13323         }
13324
13325         /* Add the declaration static const char __func__ [] = "func-name"  */
13326         fname_type = new_type(TYPE_ARRAY, 
13327                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13328         fname_type->type |= QUAL_CONST | STOR_STATIC;
13329         fname_type->elements = strlen(state->function) + 1;
13330
13331         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13332         fname->u.blob = (void *)state->function;
13333         fname = flatten(state, end, fname);
13334
13335         ident = state->i___func__;
13336         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13337
13338         /* Remember which function I am compiling.
13339          * Also assume the last defined function is the main function.
13340          */
13341         state->main_function = def;
13342
13343         /* Now get the actual function definition */
13344         compound_statement(state, end);
13345
13346         /* Finish anything unfinished with branches */
13347         resolve_branches(state, first);
13348
13349         /* Remove the parameter scope */
13350         end_scope(state);
13351
13352
13353         /* Remember I have defined a function */
13354         if (!state->functions) {
13355                 state->functions = def;
13356         } else {
13357                 insert_triple(state, state->functions, def);
13358         }
13359         if (state->compiler->debug & DEBUG_INLINE) {
13360                 FILE *fp = state->dbgout;
13361                 fprintf(fp, "\n");
13362                 loc(fp, state, 0);
13363                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13364                 display_func(state, fp, def);
13365                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13366         }
13367
13368         return def;
13369 }
13370
13371 static struct triple *do_decl(struct compile_state *state, 
13372         struct type *type, struct hash_entry *ident)
13373 {
13374         struct triple *def;
13375         def = 0;
13376         /* Clean up the storage types used */
13377         switch (type->type & STOR_MASK) {
13378         case STOR_AUTO:
13379         case STOR_STATIC:
13380                 /* These are the good types I am aiming for */
13381                 break;
13382         case STOR_REGISTER:
13383                 type->type &= ~STOR_MASK;
13384                 type->type |= STOR_AUTO;
13385                 break;
13386         case STOR_LOCAL:
13387         case STOR_EXTERN:
13388                 type->type &= ~STOR_MASK;
13389                 type->type |= STOR_STATIC;
13390                 break;
13391         case STOR_TYPEDEF:
13392                 if (!ident) {
13393                         error(state, 0, "typedef without name");
13394                 }
13395                 symbol(state, ident, &ident->sym_ident, 0, type);
13396                 ident->tok = TOK_TYPE_NAME;
13397                 return 0;
13398                 break;
13399         default:
13400                 internal_error(state, 0, "Undefined storage class");
13401         }
13402         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13403                 error(state, 0, "Function prototypes not supported");
13404         }
13405         if (ident && 
13406                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13407                 ((type->type & QUAL_CONST) == 0)) {
13408                 error(state, 0, "non const static variables not supported");
13409         }
13410         if (ident) {
13411                 def = variable(state, type);
13412                 var_symbol(state, ident, def);
13413         }
13414         return def;
13415 }
13416
13417 static void decl(struct compile_state *state, struct triple *first)
13418 {
13419         struct type *base_type, *type;
13420         struct hash_entry *ident;
13421         struct triple *def;
13422         int global;
13423         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13424         base_type = decl_specifiers(state);
13425         ident = 0;
13426         type = declarator(state, base_type, &ident, 0);
13427         type->type = attributes_opt(state, type->type);
13428         if (global && ident && (peek(state) == TOK_LBRACE)) {
13429                 /* function */
13430                 type->type_ident = ident;
13431                 state->function = ident->name;
13432                 def = function_definition(state, type);
13433                 symbol(state, ident, &ident->sym_ident, def, type);
13434                 state->function = 0;
13435         }
13436         else {
13437                 int done;
13438                 flatten(state, first, do_decl(state, type, ident));
13439                 /* type or variable definition */
13440                 do {
13441                         done = 1;
13442                         if (peek(state) == TOK_EQ) {
13443                                 if (!ident) {
13444                                         error(state, 0, "cannot assign to a type");
13445                                 }
13446                                 eat(state, TOK_EQ);
13447                                 flatten(state, first,
13448                                         init_expr(state, 
13449                                                 ident->sym_ident->def, 
13450                                                 initializer(state, type)));
13451                         }
13452                         arrays_complete(state, type);
13453                         if (peek(state) == TOK_COMMA) {
13454                                 eat(state, TOK_COMMA);
13455                                 ident = 0;
13456                                 type = declarator(state, base_type, &ident, 0);
13457                                 flatten(state, first, do_decl(state, type, ident));
13458                                 done = 0;
13459                         }
13460                 } while(!done);
13461                 eat(state, TOK_SEMI);
13462         }
13463 }
13464
13465 static void decls(struct compile_state *state)
13466 {
13467         struct triple *list;
13468         int tok;
13469         list = label(state);
13470         while(1) {
13471                 tok = peek(state);
13472                 if (tok == TOK_EOF) {
13473                         return;
13474                 }
13475                 if (tok == TOK_SPACE) {
13476                         eat(state, TOK_SPACE);
13477                 }
13478                 decl(state, list);
13479                 if (list->next != list) {
13480                         error(state, 0, "global variables not supported");
13481                 }
13482         }
13483 }
13484
13485 /* 
13486  * Function inlining
13487  */
13488 struct triple_reg_set {
13489         struct triple_reg_set *next;
13490         struct triple *member;
13491         struct triple *new;
13492 };
13493 struct reg_block {
13494         struct block *block;
13495         struct triple_reg_set *in;
13496         struct triple_reg_set *out;
13497         int vertex;
13498 };
13499 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13500 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13501 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13502 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13503 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13504         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13505         void *arg);
13506 static void print_block(
13507         struct compile_state *state, struct block *block, void *arg);
13508 static int do_triple_set(struct triple_reg_set **head, 
13509         struct triple *member, struct triple *new_member);
13510 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13511 static struct reg_block *compute_variable_lifetimes(
13512         struct compile_state *state, struct basic_blocks *bb);
13513 static void free_variable_lifetimes(struct compile_state *state, 
13514         struct basic_blocks *bb, struct reg_block *blocks);
13515 static void print_live_variables(struct compile_state *state, 
13516         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13517
13518
13519 static struct triple *call(struct compile_state *state,
13520         struct triple *retvar, struct triple *ret_addr, 
13521         struct triple *targ, struct triple *ret)
13522 {
13523         struct triple *call;
13524
13525         if (!retvar || !is_lvalue(state, retvar)) {
13526                 internal_error(state, 0, "writing to a non lvalue?");
13527         }
13528         write_compatible(state, retvar->type, &void_ptr_type);
13529
13530         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13531         TARG(call, 0) = targ;
13532         MISC(call, 0) = ret;
13533         if (!targ || (targ->op != OP_LABEL)) {
13534                 internal_error(state, 0, "call not to a label");
13535         }
13536         if (!ret || (ret->op != OP_RET)) {
13537                 internal_error(state, 0, "call not matched with return");
13538         }
13539         return call;
13540 }
13541
13542 static void walk_functions(struct compile_state *state,
13543         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13544         void *arg)
13545 {
13546         struct triple *func, *first;
13547         func = first = state->functions;
13548         do {
13549                 cb(state, func, arg);
13550                 func = func->next;
13551         } while(func != first);
13552 }
13553
13554 static void reverse_walk_functions(struct compile_state *state,
13555         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13556         void *arg)
13557 {
13558         struct triple *func, *first;
13559         func = first = state->functions;
13560         do {
13561                 func = func->prev;
13562                 cb(state, func, arg);
13563         } while(func != first);
13564 }
13565
13566
13567 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13568 {
13569         struct triple *ptr, *first;
13570         if (func->u.cval == 0) {
13571                 return;
13572         }
13573         ptr = first = RHS(func, 0);
13574         do {
13575                 if (ptr->op == OP_FCALL) {
13576                         struct triple *called_func;
13577                         called_func = MISC(ptr, 0);
13578                         /* Mark the called function as used */
13579                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13580                                 called_func->u.cval++;
13581                         }
13582                         /* Remove the called function from the list */
13583                         called_func->prev->next = called_func->next;
13584                         called_func->next->prev = called_func->prev;
13585
13586                         /* Place the called function before me on the list */
13587                         called_func->next       = func;
13588                         called_func->prev       = func->prev;
13589                         called_func->prev->next = called_func;
13590                         called_func->next->prev = called_func;
13591                 }
13592                 ptr = ptr->next;
13593         } while(ptr != first);
13594         func->id |= TRIPLE_FLAG_FLATTENED;
13595 }
13596
13597 static void mark_live_functions(struct compile_state *state)
13598 {
13599         /* Ensure state->main_function is the last function in 
13600          * the list of functions.
13601          */
13602         if ((state->main_function->next != state->functions) ||
13603                 (state->functions->prev != state->main_function)) {
13604                 internal_error(state, 0, 
13605                         "state->main_function is not at the end of the function list ");
13606         }
13607         state->main_function->u.cval = 1;
13608         reverse_walk_functions(state, mark_live, 0);
13609 }
13610
13611 static int local_triple(struct compile_state *state, 
13612         struct triple *func, struct triple *ins)
13613 {
13614         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13615 #if 0
13616         if (!local) {
13617                 FILE *fp = state->errout;
13618                 fprintf(fp, "global: ");
13619                 display_triple(fp, ins);
13620         }
13621 #endif
13622         return local;
13623 }
13624
13625 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13626         struct occurance *base_occurance)
13627 {
13628         struct triple *nfunc;
13629         struct triple *nfirst, *ofirst;
13630         struct triple *new, *old;
13631
13632         if (state->compiler->debug & DEBUG_INLINE) {
13633                 FILE *fp = state->dbgout;
13634                 fprintf(fp, "\n");
13635                 loc(fp, state, 0);
13636                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13637                 display_func(state, fp, ofunc);
13638                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13639         }
13640
13641         /* Make a new copy of the old function */
13642         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13643         nfirst = 0;
13644         ofirst = old = RHS(ofunc, 0);
13645         do {
13646                 struct triple *new;
13647                 struct occurance *occurance;
13648                 int old_lhs, old_rhs;
13649                 old_lhs = old->lhs;
13650                 old_rhs = old->rhs;
13651                 occurance = inline_occurance(state, base_occurance, old->occurance);
13652                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13653                         MISC(old, 0)->u.cval += 1;
13654                 }
13655                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13656                         occurance);
13657                 if (!triple_stores_block(state, new)) {
13658                         memcpy(&new->u, &old->u, sizeof(new->u));
13659                 }
13660                 if (!nfirst) {
13661                         RHS(nfunc, 0) = nfirst = new;
13662                 }
13663                 else {
13664                         insert_triple(state, nfirst, new);
13665                 }
13666                 new->id |= TRIPLE_FLAG_FLATTENED;
13667                 new->id |= old->id & TRIPLE_FLAG_COPY;
13668                 
13669                 /* During the copy remember new as user of old */
13670                 use_triple(old, new);
13671
13672                 /* Remember which instructions are local */
13673                 old->id |= TRIPLE_FLAG_LOCAL;
13674                 old = old->next;
13675         } while(old != ofirst);
13676
13677         /* Make a second pass to fix up any unresolved references */
13678         old = ofirst;
13679         new = nfirst;
13680         do {
13681                 struct triple **oexpr, **nexpr;
13682                 int count, i;
13683                 /* Lookup where the copy is, to join pointers */
13684                 count = TRIPLE_SIZE(old);
13685                 for(i = 0; i < count; i++) {
13686                         oexpr = &old->param[i];
13687                         nexpr = &new->param[i];
13688                         if (*oexpr && !*nexpr) {
13689                                 if (!local_triple(state, ofunc, *oexpr)) {
13690                                         *nexpr = *oexpr;
13691                                 }
13692                                 else if ((*oexpr)->use) {
13693                                         *nexpr = (*oexpr)->use->member;
13694                                 }
13695                                 if (*nexpr == old) {
13696                                         internal_error(state, 0, "new == old?");
13697                                 }
13698                                 use_triple(*nexpr, new);
13699                         }
13700                         if (!*nexpr && *oexpr) {
13701                                 internal_error(state, 0, "Could not copy %d", i);
13702                         }
13703                 }
13704                 old = old->next;
13705                 new = new->next;
13706         } while((old != ofirst) && (new != nfirst));
13707         
13708         /* Make a third pass to cleanup the extra useses */
13709         old = ofirst;
13710         new = nfirst;
13711         do {
13712                 unuse_triple(old, new);
13713                 /* Forget which instructions are local */
13714                 old->id &= ~TRIPLE_FLAG_LOCAL;
13715                 old = old->next;
13716                 new = new->next;
13717         } while ((old != ofirst) && (new != nfirst));
13718         return nfunc;
13719 }
13720
13721 static void expand_inline_call(
13722         struct compile_state *state, struct triple *me, struct triple *fcall)
13723 {
13724         /* Inline the function call */
13725         struct type *ptype;
13726         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13727         struct triple *end, *nend;
13728         int pvals, i;
13729
13730         /* Find the triples */
13731         ofunc = MISC(fcall, 0);
13732         if (ofunc->op != OP_LIST) {
13733                 internal_error(state, 0, "improper function");
13734         }
13735         nfunc = copy_func(state, ofunc, fcall->occurance);
13736         /* Prepend the parameter reading into the new function list */
13737         ptype = nfunc->type->right;
13738         pvals = fcall->rhs;
13739         for(i = 0; i < pvals; i++) {
13740                 struct type *atype;
13741                 struct triple *arg, *param;
13742                 atype = ptype;
13743                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13744                         atype = ptype->left;
13745                 }
13746                 param = farg(state, nfunc, i);
13747                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13748                         internal_error(state, fcall, "param %d type mismatch", i);
13749                 }
13750                 arg = RHS(fcall, i);
13751                 flatten(state, fcall, write_expr(state, param, arg));
13752                 ptype = ptype->right;
13753         }
13754         result = 0;
13755         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13756                 result = read_expr(state, 
13757                         deref_index(state, fresult(state, nfunc), 1));
13758         }
13759         if (state->compiler->debug & DEBUG_INLINE) {
13760                 FILE *fp = state->dbgout;
13761                 fprintf(fp, "\n");
13762                 loc(fp, state, 0);
13763                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13764                 display_func(state, fp, nfunc);
13765                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13766         }
13767
13768         /* 
13769          * Get rid of the extra triples 
13770          */
13771         /* Remove the read of the return address */
13772         ins = RHS(nfunc, 0)->prev->prev;
13773         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13774                 internal_error(state, ins, "Not return addres read?");
13775         }
13776         release_triple(state, ins);
13777         /* Remove the return instruction */
13778         ins = RHS(nfunc, 0)->prev;
13779         if (ins->op != OP_RET) {
13780                 internal_error(state, ins, "Not return?");
13781         }
13782         release_triple(state, ins);
13783         /* Remove the retaddres variable */
13784         retvar = fretaddr(state, nfunc);
13785         if ((retvar->lhs != 1) || 
13786                 (retvar->op != OP_ADECL) ||
13787                 (retvar->next->op != OP_PIECE) ||
13788                 (MISC(retvar->next, 0) != retvar)) {
13789                 internal_error(state, retvar, "Not the return address?");
13790         }
13791         release_triple(state, retvar->next);
13792         release_triple(state, retvar);
13793
13794         /* Remove the label at the start of the function */
13795         ins = RHS(nfunc, 0);
13796         if (ins->op != OP_LABEL) {
13797                 internal_error(state, ins, "Not label?");
13798         }
13799         nfirst = ins->next;
13800         free_triple(state, ins);
13801         /* Release the new function header */
13802         RHS(nfunc, 0) = 0;
13803         free_triple(state, nfunc);
13804
13805         /* Append the new function list onto the return list */
13806         end = fcall->prev;
13807         nend = nfirst->prev;
13808         end->next    = nfirst;
13809         nfirst->prev = end;
13810         nend->next   = fcall;
13811         fcall->prev  = nend;
13812
13813         /* Now the result reading code */
13814         if (result) {
13815                 result = flatten(state, fcall, result);
13816                 propogate_use(state, fcall, result);
13817         }
13818
13819         /* Release the original fcall instruction */
13820         release_triple(state, fcall);
13821
13822         return;
13823 }
13824
13825 /*
13826  *
13827  * Type of the result variable.
13828  * 
13829  *                                     result
13830  *                                        |
13831  *                             +----------+------------+
13832  *                             |                       |
13833  *                     union of closures         result_type
13834  *                             |
13835  *          +------------------+---------------+
13836  *          |                                  |
13837  *       closure1                    ...   closuerN
13838  *          |                                  | 
13839  *  +----+--+-+--------+-----+       +----+----+---+-----+
13840  *  |    |    |        |     |       |    |        |     |
13841  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13842  *                           |
13843  *                  +--------+---------+
13844  *                  |                  |
13845  *          union of closures     result_type
13846  *                  |
13847  *            +-----+-------------------+
13848  *            |                         |
13849  *         closure1            ...  closureN
13850  *            |                         |
13851  *  +-----+---+----+----+      +----+---+----+-----+
13852  *  |     |        |    |      |    |        |     |
13853  * var1 var2 ... varN result  var1 var2 ... varN result
13854  */
13855
13856 static int add_closure_type(struct compile_state *state, 
13857         struct triple *func, struct type *closure_type)
13858 {
13859         struct type *type, *ctype, **next;
13860         struct triple *var, *new_var;
13861         int i;
13862
13863 #if 0
13864         FILE *fp = state->errout;
13865         fprintf(fp, "original_type: ");
13866         name_of(fp, fresult(state, func)->type);
13867         fprintf(fp, "\n");
13868 #endif
13869         /* find the original type */
13870         var = fresult(state, func);
13871         type = var->type;
13872         if (type->elements != 2) {
13873                 internal_error(state, var, "bad return type");
13874         }
13875
13876         /* Find the complete closure type and update it */
13877         ctype = type->left->left;
13878         next = &ctype->left;
13879         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13880                 next = &(*next)->right;
13881         }
13882         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13883         ctype->elements += 1;
13884
13885 #if 0
13886         fprintf(fp, "new_type: ");
13887         name_of(fp, type);
13888         fprintf(fp, "\n");
13889         fprintf(fp, "ctype: %p %d bits: %d ", 
13890                 ctype, ctype->elements, reg_size_of(state, ctype));
13891         name_of(fp, ctype);
13892         fprintf(fp, "\n");
13893 #endif
13894         
13895         /* Regenerate the variable with the new type definition */
13896         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13897         new_var->id |= TRIPLE_FLAG_FLATTENED;
13898         for(i = 0; i < new_var->lhs; i++) {
13899                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13900         }
13901         
13902         /* Point everyone at the new variable */
13903         propogate_use(state, var, new_var);
13904
13905         /* Release the original variable */
13906         for(i = 0; i < var->lhs; i++) {
13907                 release_triple(state, LHS(var, i));
13908         }
13909         release_triple(state, var);
13910         
13911         /* Return the index of the added closure type */
13912         return ctype->elements - 1;
13913 }
13914
13915 static struct triple *closure_expr(struct compile_state *state,
13916         struct triple *func, int closure_idx, int var_idx)
13917 {
13918         return deref_index(state,
13919                 deref_index(state,
13920                         deref_index(state, fresult(state, func), 0),
13921                         closure_idx),
13922                 var_idx);
13923 }
13924
13925
13926 static void insert_triple_set(
13927         struct triple_reg_set **head, struct triple *member)
13928 {
13929         struct triple_reg_set *new;
13930         new = xcmalloc(sizeof(*new), "triple_set");
13931         new->member = member;
13932         new->new    = 0;
13933         new->next   = *head;
13934         *head       = new;
13935 }
13936
13937 static int ordered_triple_set(
13938         struct triple_reg_set **head, struct triple *member)
13939 {
13940         struct triple_reg_set **ptr;
13941         if (!member)
13942                 return 0;
13943         ptr = head;
13944         while(*ptr) {
13945                 if (member == (*ptr)->member) {
13946                         return 0;
13947                 }
13948                 /* keep the list ordered */
13949                 if (member->id < (*ptr)->member->id) {
13950                         break;
13951                 }
13952                 ptr = &(*ptr)->next;
13953         }
13954         insert_triple_set(ptr, member);
13955         return 1;
13956 }
13957
13958
13959 static void free_closure_variables(struct compile_state *state,
13960         struct triple_reg_set **enclose)
13961 {
13962         struct triple_reg_set *entry, *next;
13963         for(entry = *enclose; entry; entry = next) {
13964                 next = entry->next;
13965                 do_triple_unset(enclose, entry->member);
13966         }
13967 }
13968
13969 static int lookup_closure_index(struct compile_state *state,
13970         struct triple *me, struct triple *val)
13971 {
13972         struct triple *first, *ins, *next;
13973         first = RHS(me, 0);
13974         ins = next = first;
13975         do {
13976                 struct triple *result;
13977                 struct triple *index0, *index1, *index2, *read, *write;
13978                 ins = next;
13979                 next = ins->next;
13980                 if (ins->op != OP_CALL) {
13981                         continue;
13982                 }
13983                 /* I am at a previous call point examine it closely */
13984                 if (ins->next->op != OP_LABEL) {
13985                         internal_error(state, ins, "call not followed by label");
13986                 }
13987                 /* Does this call does not enclose any variables? */
13988                 if ((ins->next->next->op != OP_INDEX) ||
13989                         (ins->next->next->u.cval != 0) ||
13990                         (result = MISC(ins->next->next, 0)) ||
13991                         (result->id & TRIPLE_FLAG_LOCAL)) {
13992                         continue;
13993                 }
13994                 index0 = ins->next->next;
13995                 /* The pattern is:
13996                  * 0 index result < 0 >
13997                  * 1 index 0 < ? >
13998                  * 2 index 1 < ? >
13999                  * 3 read  2
14000                  * 4 write 3 var
14001                  */
14002                 for(index0 = ins->next->next;
14003                         (index0->op == OP_INDEX) &&
14004                                 (MISC(index0, 0) == result) &&
14005                                 (index0->u.cval == 0) ; 
14006                         index0 = write->next)
14007                 {
14008                         index1 = index0->next;
14009                         index2 = index1->next;
14010                         read   = index2->next;
14011                         write  = read->next;
14012                         if ((index0->op != OP_INDEX) ||
14013                                 (index1->op != OP_INDEX) ||
14014                                 (index2->op != OP_INDEX) ||
14015                                 (read->op != OP_READ) ||
14016                                 (write->op != OP_WRITE) ||
14017                                 (MISC(index1, 0) != index0) ||
14018                                 (MISC(index2, 0) != index1) ||
14019                                 (RHS(read, 0) != index2) ||
14020                                 (RHS(write, 0) != read)) {
14021                                 internal_error(state, index0, "bad var read");
14022                         }
14023                         if (MISC(write, 0) == val) {
14024                                 return index2->u.cval;
14025                         }
14026                 }
14027         } while(next != first);
14028         return -1;
14029 }
14030
14031 static inline int enclose_triple(struct triple *ins)
14032 {
14033         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
14034 }
14035
14036 static void compute_closure_variables(struct compile_state *state,
14037         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
14038 {
14039         struct triple_reg_set *set, *vars, **last_var;
14040         struct basic_blocks bb;
14041         struct reg_block *rb;
14042         struct block *block;
14043         struct triple *old_result, *first, *ins;
14044         size_t count, idx;
14045         unsigned long used_indicies;
14046         int i, max_index;
14047 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
14048 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
14049         struct { 
14050                 unsigned id;
14051                 int index;
14052         } *info;
14053
14054         
14055         /* Find the basic blocks of this function */
14056         bb.func = me;
14057         bb.first = RHS(me, 0);
14058         old_result = 0;
14059         if (!triple_is_ret(state, bb.first->prev)) {
14060                 bb.func = 0;
14061         } else {
14062                 old_result = fresult(state, me);
14063         }
14064         analyze_basic_blocks(state, &bb);
14065
14066         /* Find which variables are currently alive in a given block */
14067         rb = compute_variable_lifetimes(state, &bb);
14068
14069         /* Find the variables that are currently alive */
14070         block = block_of_triple(state, fcall);
14071         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
14072                 internal_error(state, fcall, "No reg block? block: %p", block);
14073         }
14074
14075 #if DEBUG_EXPLICIT_CLOSURES
14076         print_live_variables(state, &bb, rb, state->dbgout);
14077         fflush(state->dbgout);
14078 #endif
14079
14080         /* Count the number of triples in the function */
14081         first = RHS(me, 0);
14082         ins = first;
14083         count = 0;
14084         do {
14085                 count++;
14086                 ins = ins->next;
14087         } while(ins != first);
14088
14089         /* Allocate some memory to temorary hold the id info */
14090         info = xcmalloc(sizeof(*info) * (count +1), "info");
14091
14092         /* Mark the local function */
14093         first = RHS(me, 0);
14094         ins = first;
14095         idx = 1;
14096         do {
14097                 info[idx].id = ins->id;
14098                 ins->id = TRIPLE_FLAG_LOCAL | idx;
14099                 idx++;
14100                 ins = ins->next;
14101         } while(ins != first);
14102
14103         /* 
14104          * Build the list of variables to enclose.
14105          *
14106          * A target it to put the same variable in the
14107          * same slot for ever call of a given function.
14108          * After coloring this removes all of the variable
14109          * manipulation code.
14110          *
14111          * The list of variables to enclose is built ordered
14112          * program order because except in corner cases this
14113          * gives me the stability of assignment I need.
14114          *
14115          * To gurantee that stability I lookup the variables
14116          * to see where they have been used before and
14117          * I build my final list with the assigned indicies.
14118          */
14119         vars = 0;
14120         if (enclose_triple(old_result)) {
14121                 ordered_triple_set(&vars, old_result);
14122         }
14123         for(set = rb[block->vertex].out; set; set = set->next) {
14124                 if (!enclose_triple(set->member)) {
14125                         continue;
14126                 }
14127                 if ((set->member == fcall) || (set->member == old_result)) {
14128                         continue;
14129                 }
14130                 if (!local_triple(state, me, set->member)) {
14131                         internal_error(state, set->member, "not local?");
14132                 }
14133                 ordered_triple_set(&vars, set->member);
14134         }
14135
14136         /* Lookup the current indicies of the live varialbe */
14137         used_indicies = 0;
14138         max_index = -1;
14139         for(set = vars; set ; set = set->next) {
14140                 struct triple *ins;
14141                 int index;
14142                 ins = set->member;
14143                 index  = lookup_closure_index(state, me, ins);
14144                 info[ID_BITS(ins->id)].index = index;
14145                 if (index < 0) {
14146                         continue;
14147                 }
14148                 if (index >= MAX_INDICIES) {
14149                         internal_error(state, ins, "index unexpectedly large");
14150                 }
14151                 if (used_indicies & (1 << index)) {
14152                         internal_error(state, ins, "index previously used?");
14153                 }
14154                 /* Remember which indicies have been used */
14155                 used_indicies |= (1 << index);
14156                 if (index > max_index) {
14157                         max_index = index;
14158                 }
14159         }
14160
14161         /* Walk through the live variables and make certain
14162          * everything is assigned an index.
14163          */
14164         for(set = vars; set; set = set->next) {
14165                 struct triple *ins;
14166                 int index;
14167                 ins = set->member;
14168                 index = info[ID_BITS(ins->id)].index;
14169                 if (index >= 0) {
14170                         continue;
14171                 }
14172                 /* Find the lowest unused index value */
14173                 for(index = 0; index < MAX_INDICIES; index++) {
14174                         if (!(used_indicies & (1 << index))) {
14175                                 break;
14176                         }
14177                 }
14178                 if (index == MAX_INDICIES) {
14179                         internal_error(state, ins, "no free indicies?");
14180                 }
14181                 info[ID_BITS(ins->id)].index = index;
14182                 /* Remember which indicies have been used */
14183                 used_indicies |= (1 << index);
14184                 if (index > max_index) {
14185                         max_index = index;
14186                 }
14187         }
14188
14189         /* Build the return list of variables with positions matching
14190          * their indicies.
14191          */
14192         *enclose = 0;
14193         last_var = enclose;
14194         for(i = 0; i <= max_index; i++) {
14195                 struct triple *var;
14196                 var = 0;
14197                 if (used_indicies & (1 << i)) {
14198                         for(set = vars; set; set = set->next) {
14199                                 int index;
14200                                 index = info[ID_BITS(set->member->id)].index;
14201                                 if (index == i) {
14202                                         var = set->member;
14203                                         break;
14204                                 }
14205                         }
14206                         if (!var) {
14207                                 internal_error(state, me, "missing variable");
14208                         }
14209                 }
14210                 insert_triple_set(last_var, var);
14211                 last_var = &(*last_var)->next;
14212         }
14213
14214 #if DEBUG_EXPLICIT_CLOSURES
14215         /* Print out the variables to be enclosed */
14216         loc(state->dbgout, state, fcall);
14217         fprintf(state->dbgout, "Alive: \n");
14218         for(set = *enclose; set; set = set->next) {
14219                 display_triple(state->dbgout, set->member);
14220         }
14221         fflush(state->dbgout);
14222 #endif
14223
14224         /* Clear the marks */
14225         ins = first;
14226         do {
14227                 ins->id = info[ID_BITS(ins->id)].id;
14228                 ins = ins->next;
14229         } while(ins != first);
14230
14231         /* Release the ordered list of live variables */
14232         free_closure_variables(state, &vars);
14233
14234         /* Release the storage of the old ids */
14235         xfree(info);
14236
14237         /* Release the variable lifetime information */
14238         free_variable_lifetimes(state, &bb, rb);
14239
14240         /* Release the basic blocks of this function */
14241         free_basic_blocks(state, &bb);
14242 }
14243
14244 static void expand_function_call(
14245         struct compile_state *state, struct triple *me, struct triple *fcall)
14246 {
14247         /* Generate an ordinary function call */
14248         struct type *closure_type, **closure_next;
14249         struct triple *func, *func_first, *func_last, *retvar;
14250         struct triple *first;
14251         struct type *ptype, *rtype;
14252         struct triple *jmp;
14253         struct triple *ret_addr, *ret_loc, *ret_set;
14254         struct triple_reg_set *enclose, *set;
14255         int closure_idx, pvals, i;
14256
14257 #if DEBUG_EXPLICIT_CLOSURES
14258         FILE *fp = state->dbgout;
14259         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14260         display_func(state, fp, MISC(fcall, 0));
14261         display_func(state, fp, me);
14262         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14263 #endif
14264
14265         /* Find the triples */
14266         func = MISC(fcall, 0);
14267         func_first = RHS(func, 0);
14268         retvar = fretaddr(state, func);
14269         func_last  = func_first->prev;
14270         first = fcall->next;
14271
14272         /* Find what I need to enclose */
14273         compute_closure_variables(state, me, fcall, &enclose);
14274
14275         /* Compute the closure type */
14276         closure_type = new_type(TYPE_TUPLE, 0, 0);
14277         closure_type->elements = 0;
14278         closure_next = &closure_type->left;
14279         for(set = enclose; set ; set = set->next) {
14280                 struct type *type;
14281                 type = &void_type;
14282                 if (set->member) {
14283                         type = set->member->type;
14284                 }
14285                 if (!*closure_next) {
14286                         *closure_next = type;
14287                 } else {
14288                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14289                                 type);
14290                         closure_next = &(*closure_next)->right;
14291                 }
14292                 closure_type->elements += 1;
14293         }
14294         if (closure_type->elements == 0) {
14295                 closure_type->type = TYPE_VOID;
14296         }
14297
14298
14299 #if DEBUG_EXPLICIT_CLOSURES
14300         fprintf(state->dbgout, "closure type: ");
14301         name_of(state->dbgout, closure_type);
14302         fprintf(state->dbgout, "\n");
14303 #endif
14304
14305         /* Update the called functions closure variable */
14306         closure_idx = add_closure_type(state, func, closure_type);
14307
14308         /* Generate some needed triples */
14309         ret_loc = label(state);
14310         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14311
14312         /* Pass the parameters to the new function */
14313         ptype = func->type->right;
14314         pvals = fcall->rhs;
14315         for(i = 0; i < pvals; i++) {
14316                 struct type *atype;
14317                 struct triple *arg, *param;
14318                 atype = ptype;
14319                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14320                         atype = ptype->left;
14321                 }
14322                 param = farg(state, func, i);
14323                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14324                         internal_error(state, fcall, "param type mismatch");
14325                 }
14326                 arg = RHS(fcall, i);
14327                 flatten(state, first, write_expr(state, param, arg));
14328                 ptype = ptype->right;
14329         }
14330         rtype = func->type->left;
14331
14332         /* Thread the triples together */
14333         ret_loc       = flatten(state, first, ret_loc);
14334
14335         /* Save the active variables in the result variable */
14336         for(i = 0, set = enclose; set ; set = set->next, i++) {
14337                 if (!set->member) {
14338                         continue;
14339                 }
14340                 flatten(state, ret_loc,
14341                         write_expr(state,
14342                                 closure_expr(state, func, closure_idx, i),
14343                                 read_expr(state, set->member)));
14344         }
14345
14346         /* Initialize the return value */
14347         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14348                 flatten(state, ret_loc, 
14349                         write_expr(state, 
14350                                 deref_index(state, fresult(state, func), 1),
14351                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14352         }
14353
14354         ret_addr      = flatten(state, ret_loc, ret_addr);
14355         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14356         jmp           = flatten(state, ret_loc, 
14357                 call(state, retvar, ret_addr, func_first, func_last));
14358
14359         /* Find the result */
14360         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14361                 struct triple * result;
14362                 result = flatten(state, first, 
14363                         read_expr(state, 
14364                                 deref_index(state, fresult(state, func), 1)));
14365
14366                 propogate_use(state, fcall, result);
14367         }
14368
14369         /* Release the original fcall instruction */
14370         release_triple(state, fcall);
14371
14372         /* Restore the active variables from the result variable */
14373         for(i = 0, set = enclose; set ; set = set->next, i++) {
14374                 struct triple_set *use, *next;
14375                 struct triple *new;
14376                 struct basic_blocks bb;
14377                 if (!set->member || (set->member == fcall)) {
14378                         continue;
14379                 }
14380                 /* Generate an expression for the value */
14381                 new = flatten(state, first,
14382                         read_expr(state, 
14383                                 closure_expr(state, func, closure_idx, i)));
14384
14385
14386                 /* If the original is an lvalue restore the preserved value */
14387                 if (is_lvalue(state, set->member)) {
14388                         flatten(state, first,
14389                                 write_expr(state, set->member, new));
14390                         continue;
14391                 }
14392                 /*
14393                  * If the original is a value update the dominated uses.
14394                  */
14395                 
14396                 /* Analyze the basic blocks so I can see who dominates whom */
14397                 bb.func = me;
14398                 bb.first = RHS(me, 0);
14399                 if (!triple_is_ret(state, bb.first->prev)) {
14400                         bb.func = 0;
14401                 }
14402                 analyze_basic_blocks(state, &bb);
14403                 
14404
14405 #if DEBUG_EXPLICIT_CLOSURES
14406                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14407                         set->member, new);
14408 #endif
14409                 /* If fcall dominates the use update the expression */
14410                 for(use = set->member->use; use; use = next) {
14411                         /* Replace use modifies the use chain and 
14412                          * removes use, so I must take a copy of the
14413                          * next entry early.
14414                          */
14415                         next = use->next;
14416                         if (!tdominates(state, fcall, use->member)) {
14417                                 continue;
14418                         }
14419                         replace_use(state, set->member, new, use->member);
14420                 }
14421
14422                 /* Release the basic blocks, the instructions will be
14423                  * different next time, and flatten/insert_triple does
14424                  * not update the block values so I can't cache the analysis.
14425                  */
14426                 free_basic_blocks(state, &bb);
14427         }
14428
14429         /* Release the closure variable list */
14430         free_closure_variables(state, &enclose);
14431
14432         if (state->compiler->debug & DEBUG_INLINE) {
14433                 FILE *fp = state->dbgout;
14434                 fprintf(fp, "\n");
14435                 loc(fp, state, 0);
14436                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14437                 display_func(state, fp, func);
14438                 display_func(state, fp, me);
14439                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14440         }
14441
14442         return;
14443 }
14444
14445 static int do_inline(struct compile_state *state, struct triple *func)
14446 {
14447         int do_inline;
14448         int policy;
14449
14450         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14451         switch(policy) {
14452         case COMPILER_INLINE_ALWAYS:
14453                 do_inline = 1;
14454                 if (func->type->type & ATTRIB_NOINLINE) {
14455                         error(state, func, "noinline with always_inline compiler option");
14456                 }
14457                 break;
14458         case COMPILER_INLINE_NEVER:
14459                 do_inline = 0;
14460                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14461                         error(state, func, "always_inline with noinline compiler option");
14462                 }
14463                 break;
14464         case COMPILER_INLINE_DEFAULTON:
14465                 switch(func->type->type & STOR_MASK) {
14466                 case STOR_STATIC | STOR_INLINE:
14467                 case STOR_LOCAL  | STOR_INLINE:
14468                 case STOR_EXTERN | STOR_INLINE:
14469                         do_inline = 1;
14470                         break;
14471                 default:
14472                         do_inline = 1;
14473                         break;
14474                 }
14475                 break;
14476         case COMPILER_INLINE_DEFAULTOFF:
14477                 switch(func->type->type & STOR_MASK) {
14478                 case STOR_STATIC | STOR_INLINE:
14479                 case STOR_LOCAL  | STOR_INLINE:
14480                 case STOR_EXTERN | STOR_INLINE:
14481                         do_inline = 1;
14482                         break;
14483                 default:
14484                         do_inline = 0;
14485                         break;
14486                 }
14487                 break;
14488         case COMPILER_INLINE_NOPENALTY:
14489                 switch(func->type->type & STOR_MASK) {
14490                 case STOR_STATIC | STOR_INLINE:
14491                 case STOR_LOCAL  | STOR_INLINE:
14492                 case STOR_EXTERN | STOR_INLINE:
14493                         do_inline = 1;
14494                         break;
14495                 default:
14496                         do_inline = (func->u.cval == 1);
14497                         break;
14498                 }
14499                 break;
14500         default:
14501                 do_inline = 0;
14502                 internal_error(state, 0, "Unimplemented inline policy");
14503                 break;
14504         }
14505         /* Force inlining */
14506         if (func->type->type & ATTRIB_NOINLINE) {
14507                 do_inline = 0;
14508         }
14509         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14510                 do_inline = 1;
14511         }
14512         return do_inline;
14513 }
14514
14515 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14516 {
14517         struct triple *first, *ptr, *next;
14518         /* If the function is not used don't bother */
14519         if (me->u.cval <= 0) {
14520                 return;
14521         }
14522         if (state->compiler->debug & DEBUG_CALLS2) {
14523                 FILE *fp = state->dbgout;
14524                 fprintf(fp, "in: %s\n",
14525                         me->type->type_ident->name);
14526         }
14527
14528         first = RHS(me, 0);
14529         ptr = next = first;
14530         do {
14531                 struct triple *func, *prev;
14532                 ptr = next;
14533                 prev = ptr->prev;
14534                 next = ptr->next;
14535                 if (ptr->op != OP_FCALL) {
14536                         continue;
14537                 }
14538                 func = MISC(ptr, 0);
14539                 /* See if the function should be inlined */
14540                 if (!do_inline(state, func)) {
14541                         /* Put a label after the fcall */
14542                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14543                         continue;
14544                 }
14545                 if (state->compiler->debug & DEBUG_CALLS) {
14546                         FILE *fp = state->dbgout;
14547                         if (state->compiler->debug & DEBUG_CALLS2) {
14548                                 loc(fp, state, ptr);
14549                         }
14550                         fprintf(fp, "inlining %s\n",
14551                                 func->type->type_ident->name);
14552                         fflush(fp);
14553                 }
14554
14555                 /* Update the function use counts */
14556                 func->u.cval -= 1;
14557
14558                 /* Replace the fcall with the called function */
14559                 expand_inline_call(state, me, ptr);
14560
14561                 next = prev->next;
14562         } while (next != first);
14563
14564         ptr = next = first;
14565         do {
14566                 struct triple *prev, *func;
14567                 ptr = next;
14568                 prev = ptr->prev;
14569                 next = ptr->next;
14570                 if (ptr->op != OP_FCALL) {
14571                         continue;
14572                 }
14573                 func = MISC(ptr, 0);
14574                 if (state->compiler->debug & DEBUG_CALLS) {
14575                         FILE *fp = state->dbgout;
14576                         if (state->compiler->debug & DEBUG_CALLS2) {
14577                                 loc(fp, state, ptr);
14578                         }
14579                         fprintf(fp, "calling %s\n",
14580                                 func->type->type_ident->name);
14581                         fflush(fp);
14582                 }
14583                 /* Replace the fcall with the instruction sequence
14584                  * needed to make the call.
14585                  */
14586                 expand_function_call(state, me, ptr);
14587                 next = prev->next;
14588         } while(next != first);
14589 }
14590
14591 static void inline_functions(struct compile_state *state, struct triple *func)
14592 {
14593         inline_function(state, func, 0);
14594         reverse_walk_functions(state, inline_function, 0);
14595 }
14596
14597 static void insert_function(struct compile_state *state,
14598         struct triple *func, void *arg)
14599 {
14600         struct triple *first, *end, *ffirst, *fend;
14601
14602         if (state->compiler->debug & DEBUG_INLINE) {
14603                 FILE *fp = state->errout;
14604                 fprintf(fp, "%s func count: %d\n", 
14605                         func->type->type_ident->name, func->u.cval);
14606         }
14607         if (func->u.cval == 0) {
14608                 return;
14609         }
14610
14611         /* Find the end points of the lists */
14612         first  = arg;
14613         end    = first->prev;
14614         ffirst = RHS(func, 0);
14615         fend   = ffirst->prev;
14616
14617         /* splice the lists together */
14618         end->next    = ffirst;
14619         ffirst->prev = end;
14620         fend->next   = first;
14621         first->prev  = fend;
14622 }
14623
14624 struct triple *input_asm(struct compile_state *state)
14625 {
14626         struct asm_info *info;
14627         struct triple *def;
14628         int i, out;
14629         
14630         info = xcmalloc(sizeof(*info), "asm_info");
14631         info->str = "";
14632
14633         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14634         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14635
14636         def = new_triple(state, OP_ASM, &void_type, out, 0);
14637         def->u.ainfo = info;
14638         def->id |= TRIPLE_FLAG_VOLATILE;
14639         
14640         for(i = 0; i < out; i++) {
14641                 struct triple *piece;
14642                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14643                 piece->u.cval = i;
14644                 LHS(def, i) = piece;
14645         }
14646
14647         return def;
14648 }
14649
14650 struct triple *output_asm(struct compile_state *state)
14651 {
14652         struct asm_info *info;
14653         struct triple *def;
14654         int in;
14655         
14656         info = xcmalloc(sizeof(*info), "asm_info");
14657         info->str = "";
14658
14659         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14660         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14661
14662         def = new_triple(state, OP_ASM, &void_type, 0, in);
14663         def->u.ainfo = info;
14664         def->id |= TRIPLE_FLAG_VOLATILE;
14665         
14666         return def;
14667 }
14668
14669 static void join_functions(struct compile_state *state)
14670 {
14671         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14672         struct file_state file;
14673         struct type *pnext, *param;
14674         struct type *result_type, *args_type;
14675         int idx;
14676
14677         /* Be clear the functions have not been joined yet */
14678         state->functions_joined = 0;
14679
14680         /* Dummy file state to get debug handing right */
14681         memset(&file, 0, sizeof(file));
14682         file.basename = "";
14683         file.line = 0;
14684         file.report_line = 0;
14685         file.report_name = file.basename;
14686         file.prev = state->file;
14687         state->file = &file;
14688         state->function = "";
14689
14690         if (!state->main_function) {
14691                 error(state, 0, "No functions to compile\n");
14692         }
14693
14694         /* The type of arguments */
14695         args_type   = state->main_function->type->right;
14696         /* The return type without any specifiers */
14697         result_type = clone_type(0, state->main_function->type->left);
14698
14699
14700         /* Verify the external arguments */
14701         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14702                 error(state, state->main_function, 
14703                         "Too many external input arguments");
14704         }
14705         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14706                 error(state, state->main_function, 
14707                         "Too many external output arguments");
14708         }
14709
14710         /* Lay down the basic program structure */
14711         end           = label(state);
14712         start         = label(state);
14713         start         = flatten(state, state->first, start);
14714         end           = flatten(state, state->first, end);
14715         in            = input_asm(state);
14716         out           = output_asm(state);
14717         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14718         MISC(call, 0) = state->main_function;
14719         in            = flatten(state, state->first, in);
14720         call          = flatten(state, state->first, call);
14721         out           = flatten(state, state->first, out);
14722
14723
14724         /* Read the external input arguments */
14725         pnext = args_type;
14726         idx = 0;
14727         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14728                 struct triple *expr;
14729                 param = pnext;
14730                 pnext = 0;
14731                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14732                         pnext = param->right;
14733                         param = param->left;
14734                 }
14735                 if (registers_of(state, param) != 1) {
14736                         error(state, state->main_function, 
14737                                 "Arg: %d %s requires multiple registers", 
14738                                 idx + 1, param->field_ident->name);
14739                 }
14740                 expr = read_expr(state, LHS(in, idx));
14741                 RHS(call, idx) = expr;
14742                 expr = flatten(state, call, expr);
14743                 use_triple(expr, call);
14744
14745                 idx++;  
14746         }
14747
14748
14749         /* Write the external output arguments */
14750         pnext = result_type;
14751         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14752                 pnext = result_type->left;
14753         }
14754         for(idx = 0; idx < out->rhs; idx++) {
14755                 struct triple *expr;
14756                 param = pnext;
14757                 pnext = 0;
14758                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14759                         pnext = param->right;
14760                         param = param->left;
14761                 }
14762                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14763                         param = 0;
14764                 }
14765                 if (param) {
14766                         if (registers_of(state, param) != 1) {
14767                                 error(state, state->main_function,
14768                                         "Result: %d %s requires multiple registers",
14769                                         idx, param->field_ident->name);
14770                         }
14771                         expr = read_expr(state, call);
14772                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14773                                 expr = deref_field(state, expr, param->field_ident);
14774                         }
14775                 } else {
14776                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14777                 }
14778                 flatten(state, out, expr);
14779                 RHS(out, idx) = expr;
14780                 use_triple(expr, out);
14781         }
14782
14783         /* Allocate a dummy containing function */
14784         func = triple(state, OP_LIST, 
14785                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14786         func->type->type_ident = lookup(state, "", 0);
14787         RHS(func, 0) = state->first;
14788         func->u.cval = 1;
14789
14790         /* See which functions are called, and how often */
14791         mark_live_functions(state);
14792         inline_functions(state, func);
14793         walk_functions(state, insert_function, end);
14794
14795         if (start->next != end) {
14796                 jmp = flatten(state, start, branch(state, end, 0));
14797         }
14798
14799         /* OK now the functions have been joined. */
14800         state->functions_joined = 1;
14801
14802         /* Done now cleanup */
14803         state->file = file.prev;
14804         state->function = 0;
14805 }
14806
14807 /*
14808  * Data structurs for optimation.
14809  */
14810
14811
14812 static int do_use_block(
14813         struct block *used, struct block_set **head, struct block *user, 
14814         int front)
14815 {
14816         struct block_set **ptr, *new;
14817         if (!used)
14818                 return 0;
14819         if (!user)
14820                 return 0;
14821         ptr = head;
14822         while(*ptr) {
14823                 if ((*ptr)->member == user) {
14824                         return 0;
14825                 }
14826                 ptr = &(*ptr)->next;
14827         }
14828         new = xcmalloc(sizeof(*new), "block_set");
14829         new->member = user;
14830         if (front) {
14831                 new->next = *head;
14832                 *head = new;
14833         }
14834         else {
14835                 new->next = 0;
14836                 *ptr = new;
14837         }
14838         return 1;
14839 }
14840 static int do_unuse_block(
14841         struct block *used, struct block_set **head, struct block *unuser)
14842 {
14843         struct block_set *use, **ptr;
14844         int count;
14845         count = 0;
14846         ptr = head;
14847         while(*ptr) {
14848                 use = *ptr;
14849                 if (use->member == unuser) {
14850                         *ptr = use->next;
14851                         memset(use, -1, sizeof(*use));
14852                         xfree(use);
14853                         count += 1;
14854                 }
14855                 else {
14856                         ptr = &use->next;
14857                 }
14858         }
14859         return count;
14860 }
14861
14862 static void use_block(struct block *used, struct block *user)
14863 {
14864         int count;
14865         /* Append new to the head of the list, print_block
14866          * depends on this.
14867          */
14868         count = do_use_block(used, &used->use, user, 1); 
14869         used->users += count;
14870 }
14871 static void unuse_block(struct block *used, struct block *unuser)
14872 {
14873         int count;
14874         count = do_unuse_block(used, &used->use, unuser); 
14875         used->users -= count;
14876 }
14877
14878 static void add_block_edge(struct block *block, struct block *edge, int front)
14879 {
14880         int count;
14881         count = do_use_block(block, &block->edges, edge, front);
14882         block->edge_count += count;
14883 }
14884
14885 static void remove_block_edge(struct block *block, struct block *edge)
14886 {
14887         int count;
14888         count = do_unuse_block(block, &block->edges, edge);
14889         block->edge_count -= count;
14890 }
14891
14892 static void idom_block(struct block *idom, struct block *user)
14893 {
14894         do_use_block(idom, &idom->idominates, user, 0);
14895 }
14896
14897 static void unidom_block(struct block *idom, struct block *unuser)
14898 {
14899         do_unuse_block(idom, &idom->idominates, unuser);
14900 }
14901
14902 static void domf_block(struct block *block, struct block *domf)
14903 {
14904         do_use_block(block, &block->domfrontier, domf, 0);
14905 }
14906
14907 static void undomf_block(struct block *block, struct block *undomf)
14908 {
14909         do_unuse_block(block, &block->domfrontier, undomf);
14910 }
14911
14912 static void ipdom_block(struct block *ipdom, struct block *user)
14913 {
14914         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14915 }
14916
14917 static void unipdom_block(struct block *ipdom, struct block *unuser)
14918 {
14919         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14920 }
14921
14922 static void ipdomf_block(struct block *block, struct block *ipdomf)
14923 {
14924         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14925 }
14926
14927 static void unipdomf_block(struct block *block, struct block *unipdomf)
14928 {
14929         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14930 }
14931
14932 static int walk_triples(
14933         struct compile_state *state, 
14934         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14935         void *arg)
14936 {
14937         struct triple *ptr;
14938         int result;
14939         ptr = state->first;
14940         do {
14941                 result = cb(state, ptr, arg);
14942                 if (ptr->next->prev != ptr) {
14943                         internal_error(state, ptr->next, "bad prev");
14944                 }
14945                 ptr = ptr->next;
14946         } while((result == 0) && (ptr != state->first));
14947         return result;
14948 }
14949
14950 #define PRINT_LIST 1
14951 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
14952 {
14953         FILE *fp = arg;
14954         int op;
14955         op = ins->op;
14956         if (op == OP_LIST) {
14957 #if !PRINT_LIST
14958                 return 0;
14959 #endif
14960         }
14961         if ((op == OP_LABEL) && (ins->use)) {
14962                 fprintf(fp, "\n%p:\n", ins);
14963         }
14964         display_triple(fp, ins);
14965
14966         if (triple_is_branch(state, ins) && ins->use && 
14967                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
14968                 internal_error(state, ins, "branch used?");
14969         }
14970         if (triple_is_branch(state, ins)) {
14971                 fprintf(fp, "\n");
14972         }
14973         return 0;
14974 }
14975
14976 static void print_triples(struct compile_state *state)
14977 {
14978         if (state->compiler->debug & DEBUG_TRIPLES) {
14979                 FILE *fp = state->dbgout;
14980                 fprintf(fp, "--------------- triples ---------------\n");
14981                 walk_triples(state, do_print_triple, fp);
14982                 fprintf(fp, "\n");
14983         }
14984 }
14985
14986 struct cf_block {
14987         struct block *block;
14988 };
14989 static void find_cf_blocks(struct cf_block *cf, struct block *block)
14990 {
14991         struct block_set *edge;
14992         if (!block || (cf[block->vertex].block == block)) {
14993                 return;
14994         }
14995         cf[block->vertex].block = block;
14996         for(edge = block->edges; edge; edge = edge->next) {
14997                 find_cf_blocks(cf, edge->member);
14998         }
14999 }
15000
15001 static void print_control_flow(struct compile_state *state,
15002         FILE *fp, struct basic_blocks *bb)
15003 {
15004         struct cf_block *cf;
15005         int i;
15006         fprintf(fp, "\ncontrol flow\n");
15007         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
15008         find_cf_blocks(cf, bb->first_block);
15009
15010         for(i = 1; i <= bb->last_vertex; i++) {
15011                 struct block *block;
15012                 struct block_set *edge;
15013                 block = cf[i].block;
15014                 if (!block)
15015                         continue;
15016                 fprintf(fp, "(%p) %d:", block, block->vertex);
15017                 for(edge = block->edges; edge; edge = edge->next) {
15018                         fprintf(fp, " %d", edge->member->vertex);
15019                 }
15020                 fprintf(fp, "\n");
15021         }
15022
15023         xfree(cf);
15024 }
15025
15026 static void free_basic_block(struct compile_state *state, struct block *block)
15027 {
15028         struct block_set *edge, *entry;
15029         struct block *child;
15030         if (!block) {
15031                 return;
15032         }
15033         if (block->vertex == -1) {
15034                 return;
15035         }
15036         block->vertex = -1;
15037         for(edge = block->edges; edge; edge = edge->next) {
15038                 if (edge->member) {
15039                         unuse_block(edge->member, block);
15040                 }
15041         }
15042         if (block->idom) {
15043                 unidom_block(block->idom, block);
15044         }
15045         block->idom = 0;
15046         if (block->ipdom) {
15047                 unipdom_block(block->ipdom, block);
15048         }
15049         block->ipdom = 0;
15050         while((entry = block->use)) {
15051                 child = entry->member;
15052                 unuse_block(block, child);
15053                 if (child && (child->vertex != -1)) {
15054                         for(edge = child->edges; edge; edge = edge->next) {
15055                                 edge->member = 0;
15056                         }
15057                 }
15058         }
15059         while((entry = block->idominates)) {
15060                 child = entry->member;
15061                 unidom_block(block, child);
15062                 if (child && (child->vertex != -1)) {
15063                         child->idom = 0;
15064                 }
15065         }
15066         while((entry = block->domfrontier)) {
15067                 child = entry->member;
15068                 undomf_block(block, child);
15069         }
15070         while((entry = block->ipdominates)) {
15071                 child = entry->member;
15072                 unipdom_block(block, child);
15073                 if (child && (child->vertex != -1)) {
15074                         child->ipdom = 0;
15075                 }
15076         }
15077         while((entry = block->ipdomfrontier)) {
15078                 child = entry->member;
15079                 unipdomf_block(block, child);
15080         }
15081         if (block->users != 0) {
15082                 internal_error(state, 0, "block still has users");
15083         }
15084         while((edge = block->edges)) {
15085                 child = edge->member;
15086                 remove_block_edge(block, child);
15087                 
15088                 if (child && (child->vertex != -1)) {
15089                         free_basic_block(state, child);
15090                 }
15091         }
15092         memset(block, -1, sizeof(*block));
15093         xfree(block);
15094 }
15095
15096 static void free_basic_blocks(struct compile_state *state, 
15097         struct basic_blocks *bb)
15098 {
15099         struct triple *first, *ins;
15100         free_basic_block(state, bb->first_block);
15101         bb->last_vertex = 0;
15102         bb->first_block = bb->last_block = 0;
15103         first = bb->first;
15104         ins = first;
15105         do {
15106                 if (triple_stores_block(state, ins)) {
15107                         ins->u.block = 0;
15108                 }
15109                 ins = ins->next;
15110         } while(ins != first);
15111         
15112 }
15113
15114 static struct block *basic_block(struct compile_state *state, 
15115         struct basic_blocks *bb, struct triple *first)
15116 {
15117         struct block *block;
15118         struct triple *ptr;
15119         if (!triple_is_label(state, first)) {
15120                 internal_error(state, first, "block does not start with a label");
15121         }
15122         /* See if this basic block has already been setup */
15123         if (first->u.block != 0) {
15124                 return first->u.block;
15125         }
15126         /* Allocate another basic block structure */
15127         bb->last_vertex += 1;
15128         block = xcmalloc(sizeof(*block), "block");
15129         block->first = block->last = first;
15130         block->vertex = bb->last_vertex;
15131         ptr = first;
15132         do {
15133                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
15134                         break;
15135                 }
15136                 block->last = ptr;
15137                 /* If ptr->u is not used remember where the baic block is */
15138                 if (triple_stores_block(state, ptr)) {
15139                         ptr->u.block = block;
15140                 }
15141                 if (triple_is_branch(state, ptr)) {
15142                         break;
15143                 }
15144                 ptr = ptr->next;
15145         } while (ptr != bb->first);
15146         if ((ptr == bb->first) ||
15147                 ((ptr->next == bb->first) && (
15148                         triple_is_end(state, ptr) || 
15149                         triple_is_ret(state, ptr))))
15150         {
15151                 /* The block has no outflowing edges */
15152         }
15153         else if (triple_is_label(state, ptr)) {
15154                 struct block *next;
15155                 next = basic_block(state, bb, ptr);
15156                 add_block_edge(block, next, 0);
15157                 use_block(next, block);
15158         }
15159         else if (triple_is_branch(state, ptr)) {
15160                 struct triple **expr, *first;
15161                 struct block *child;
15162                 /* Find the branch targets.
15163                  * I special case the first branch as that magically
15164                  * avoids some difficult cases for the register allocator.
15165                  */
15166                 expr = triple_edge_targ(state, ptr, 0);
15167                 if (!expr) {
15168                         internal_error(state, ptr, "branch without targets");
15169                 }
15170                 first = *expr;
15171                 expr = triple_edge_targ(state, ptr, expr);
15172                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15173                         if (!*expr) continue;
15174                         child = basic_block(state, bb, *expr);
15175                         use_block(child, block);
15176                         add_block_edge(block, child, 0);
15177                 }
15178                 if (first) {
15179                         child = basic_block(state, bb, first);
15180                         use_block(child, block);
15181                         add_block_edge(block, child, 1);
15182
15183                         /* Be certain the return block of a call is
15184                          * in a basic block.  When it is not find
15185                          * start of the block, insert a label if
15186                          * necessary and build the basic block.
15187                          * Then add a fake edge from the start block
15188                          * to the return block of the function.
15189                          */
15190                         if (state->functions_joined && triple_is_call(state, ptr)
15191                                 && !block_of_triple(state, MISC(ptr, 0))) {
15192                                 struct block *tail;
15193                                 struct triple *start;
15194                                 start = triple_to_block_start(state, MISC(ptr, 0));
15195                                 if (!triple_is_label(state, start)) {
15196                                         start = pre_triple(state,
15197                                                 start, OP_LABEL, &void_type, 0, 0);
15198                                 }
15199                                 tail = basic_block(state, bb, start);
15200                                 add_block_edge(child, tail, 0);
15201                                 use_block(tail, child);
15202                         }
15203                 }
15204         }
15205         else {
15206                 internal_error(state, 0, "Bad basic block split");
15207         }
15208 #if 0
15209 {
15210         struct block_set *edge;
15211         FILE *fp = state->errout;
15212         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15213                 block, block->vertex, 
15214                 block->first, block->last);
15215         for(edge = block->edges; edge; edge = edge->next) {
15216                 fprintf(fp, " %10p [%2d]",
15217                         edge->member ? edge->member->first : 0,
15218                         edge->member ? edge->member->vertex : -1);
15219         }
15220         fprintf(fp, "\n");
15221 }
15222 #endif
15223         return block;
15224 }
15225
15226
15227 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15228         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15229         void *arg)
15230 {
15231         struct triple *ptr, *first;
15232         struct block *last_block;
15233         last_block = 0;
15234         first = bb->first;
15235         ptr = first;
15236         do {
15237                 if (triple_stores_block(state, ptr)) {
15238                         struct block *block;
15239                         block = ptr->u.block;
15240                         if (block && (block != last_block)) {
15241                                 cb(state, block, arg);
15242                         }
15243                         last_block = block;
15244                 }
15245                 ptr = ptr->next;
15246         } while(ptr != first);
15247 }
15248
15249 static void print_block(
15250         struct compile_state *state, struct block *block, void *arg)
15251 {
15252         struct block_set *user, *edge;
15253         struct triple *ptr;
15254         FILE *fp = arg;
15255
15256         fprintf(fp, "\nblock: %p (%d) ",
15257                 block, 
15258                 block->vertex);
15259
15260         for(edge = block->edges; edge; edge = edge->next) {
15261                 fprintf(fp, " %p<-%p",
15262                         edge->member,
15263                         (edge->member && edge->member->use)?
15264                         edge->member->use->member : 0);
15265         }
15266         fprintf(fp, "\n");
15267         if (block->first->op == OP_LABEL) {
15268                 fprintf(fp, "%p:\n", block->first);
15269         }
15270         for(ptr = block->first; ; ) {
15271                 display_triple(fp, ptr);
15272                 if (ptr == block->last)
15273                         break;
15274                 ptr = ptr->next;
15275                 if (ptr == block->first) {
15276                         internal_error(state, 0, "missing block last?");
15277                 }
15278         }
15279         fprintf(fp, "users %d: ", block->users);
15280         for(user = block->use; user; user = user->next) {
15281                 fprintf(fp, "%p (%d) ", 
15282                         user->member,
15283                         user->member->vertex);
15284         }
15285         fprintf(fp,"\n\n");
15286 }
15287
15288
15289 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15290 {
15291         fprintf(fp, "--------------- blocks ---------------\n");
15292         walk_blocks(state, &state->bb, print_block, fp);
15293 }
15294 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15295 {
15296         static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15297         static void print_dominance_frontiers(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15298         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15299                 fprintf(fp, "After %s\n", func);
15300                 romcc_print_blocks(state, fp);
15301                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15302                         print_dominators(state, fp, &state->bb);
15303                         print_dominance_frontiers(state, fp, &state->bb);
15304                 }
15305                 print_control_flow(state, fp, &state->bb);
15306         }
15307 }
15308
15309 static void prune_nonblock_triples(struct compile_state *state, 
15310         struct basic_blocks *bb)
15311 {
15312         struct block *block;
15313         struct triple *first, *ins, *next;
15314         /* Delete the triples not in a basic block */
15315         block = 0;
15316         first = bb->first;
15317         ins = first;
15318         do {
15319                 next = ins->next;
15320                 if (ins->op == OP_LABEL) {
15321                         block = ins->u.block;
15322                 }
15323                 if (!block) {
15324                         struct triple_set *use;
15325                         for(use = ins->use; use; use = use->next) {
15326                                 struct block *block;
15327                                 block = block_of_triple(state, use->member);
15328                                 if (block != 0) {
15329                                         internal_error(state, ins, "pruning used ins?");
15330                                 }
15331                         }
15332                         release_triple(state, ins);
15333                 }
15334                 if (block && block->last == ins) {
15335                         block = 0;
15336                 }
15337                 ins = next;
15338         } while(ins != first);
15339 }
15340
15341 static void setup_basic_blocks(struct compile_state *state, 
15342         struct basic_blocks *bb)
15343 {
15344         if (!triple_stores_block(state, bb->first)) {
15345                 internal_error(state, 0, "ins will not store block?");
15346         }
15347         /* Initialize the state */
15348         bb->first_block = bb->last_block = 0;
15349         bb->last_vertex = 0;
15350         free_basic_blocks(state, bb);
15351
15352         /* Find the basic blocks */
15353         bb->first_block = basic_block(state, bb, bb->first);
15354
15355         /* Be certain the last instruction of a function, or the
15356          * entire program is in a basic block.  When it is not find 
15357          * the start of the block, insert a label if necessary and build 
15358          * basic block.  Then add a fake edge from the start block
15359          * to the final block.
15360          */
15361         if (!block_of_triple(state, bb->first->prev)) {
15362                 struct triple *start;
15363                 struct block *tail;
15364                 start = triple_to_block_start(state, bb->first->prev);
15365                 if (!triple_is_label(state, start)) {
15366                         start = pre_triple(state,
15367                                 start, OP_LABEL, &void_type, 0, 0);
15368                 }
15369                 tail = basic_block(state, bb, start);
15370                 add_block_edge(bb->first_block, tail, 0);
15371                 use_block(tail, bb->first_block);
15372         }
15373         
15374         /* Find the last basic block.
15375          */
15376         bb->last_block = block_of_triple(state, bb->first->prev);
15377
15378         /* Delete the triples not in a basic block */
15379         prune_nonblock_triples(state, bb);
15380
15381 #if 0
15382         /* If we are debugging print what I have just done */
15383         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15384                 print_blocks(state, state->dbgout);
15385                 print_control_flow(state, bb);
15386         }
15387 #endif
15388 }
15389
15390
15391 struct sdom_block {
15392         struct block *block;
15393         struct sdom_block *sdominates;
15394         struct sdom_block *sdom_next;
15395         struct sdom_block *sdom;
15396         struct sdom_block *label;
15397         struct sdom_block *parent;
15398         struct sdom_block *ancestor;
15399         int vertex;
15400 };
15401
15402
15403 static void unsdom_block(struct sdom_block *block)
15404 {
15405         struct sdom_block **ptr;
15406         if (!block->sdom_next) {
15407                 return;
15408         }
15409         ptr = &block->sdom->sdominates;
15410         while(*ptr) {
15411                 if ((*ptr) == block) {
15412                         *ptr = block->sdom_next;
15413                         return;
15414                 }
15415                 ptr = &(*ptr)->sdom_next;
15416         }
15417 }
15418
15419 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15420 {
15421         unsdom_block(block);
15422         block->sdom = sdom;
15423         block->sdom_next = sdom->sdominates;
15424         sdom->sdominates = block;
15425 }
15426
15427
15428
15429 static int initialize_sdblock(struct sdom_block *sd,
15430         struct block *parent, struct block *block, int vertex)
15431 {
15432         struct block_set *edge;
15433         if (!block || (sd[block->vertex].block == block)) {
15434                 return vertex;
15435         }
15436         vertex += 1;
15437         /* Renumber the blocks in a convinient fashion */
15438         block->vertex = vertex;
15439         sd[vertex].block    = block;
15440         sd[vertex].sdom     = &sd[vertex];
15441         sd[vertex].label    = &sd[vertex];
15442         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15443         sd[vertex].ancestor = 0;
15444         sd[vertex].vertex   = vertex;
15445         for(edge = block->edges; edge; edge = edge->next) {
15446                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15447         }
15448         return vertex;
15449 }
15450
15451 static int initialize_spdblock(
15452         struct compile_state *state, struct sdom_block *sd,
15453         struct block *parent, struct block *block, int vertex)
15454 {
15455         struct block_set *user;
15456         if (!block || (sd[block->vertex].block == block)) {
15457                 return vertex;
15458         }
15459         vertex += 1;
15460         /* Renumber the blocks in a convinient fashion */
15461         block->vertex = vertex;
15462         sd[vertex].block    = block;
15463         sd[vertex].sdom     = &sd[vertex];
15464         sd[vertex].label    = &sd[vertex];
15465         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15466         sd[vertex].ancestor = 0;
15467         sd[vertex].vertex   = vertex;
15468         for(user = block->use; user; user = user->next) {
15469                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15470         }
15471         return vertex;
15472 }
15473
15474 static int setup_spdblocks(struct compile_state *state, 
15475         struct basic_blocks *bb, struct sdom_block *sd)
15476 {
15477         struct block *block;
15478         int vertex;
15479         /* Setup as many sdpblocks as possible without using fake edges */
15480         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15481
15482         /* Walk through the graph and find unconnected blocks.  Add a
15483          * fake edge from the unconnected blocks to the end of the
15484          * graph. 
15485          */
15486         block = bb->first_block->last->next->u.block;
15487         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15488                 if (sd[block->vertex].block == block) {
15489                         continue;
15490                 }
15491 #if DEBUG_SDP_BLOCKS
15492                 {
15493                         FILE *fp = state->errout;
15494                         fprintf(fp, "Adding %d\n", vertex +1);
15495                 }
15496 #endif
15497                 add_block_edge(block, bb->last_block, 0);
15498                 use_block(bb->last_block, block);
15499
15500                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15501         }
15502         return vertex;
15503 }
15504
15505 static void compress_ancestors(struct sdom_block *v)
15506 {
15507         /* This procedure assumes ancestor(v) != 0 */
15508         /* if (ancestor(ancestor(v)) != 0) {
15509          *      compress(ancestor(ancestor(v)));
15510          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15511          *              label(v) = label(ancestor(v));
15512          *      }
15513          *      ancestor(v) = ancestor(ancestor(v));
15514          * }
15515          */
15516         if (!v->ancestor) {
15517                 return;
15518         }
15519         if (v->ancestor->ancestor) {
15520                 compress_ancestors(v->ancestor->ancestor);
15521                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15522                         v->label = v->ancestor->label;
15523                 }
15524                 v->ancestor = v->ancestor->ancestor;
15525         }
15526 }
15527
15528 static void compute_sdom(struct compile_state *state, 
15529         struct basic_blocks *bb, struct sdom_block *sd)
15530 {
15531         int i;
15532         /* // step 2 
15533          *  for each v <= pred(w) {
15534          *      u = EVAL(v);
15535          *      if (semi[u] < semi[w] { 
15536          *              semi[w] = semi[u]; 
15537          *      } 
15538          * }
15539          * add w to bucket(vertex(semi[w]));
15540          * LINK(parent(w), w);
15541          *
15542          * // step 3
15543          * for each v <= bucket(parent(w)) {
15544          *      delete v from bucket(parent(w));
15545          *      u = EVAL(v);
15546          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15547          * }
15548          */
15549         for(i = bb->last_vertex; i >= 2; i--) {
15550                 struct sdom_block *v, *parent, *next;
15551                 struct block_set *user;
15552                 struct block *block;
15553                 block = sd[i].block;
15554                 parent = sd[i].parent;
15555                 /* Step 2 */
15556                 for(user = block->use; user; user = user->next) {
15557                         struct sdom_block *v, *u;
15558                         v = &sd[user->member->vertex];
15559                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15560                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15561                                 sd[i].sdom = u->sdom;
15562                         }
15563                 }
15564                 sdom_block(sd[i].sdom, &sd[i]);
15565                 sd[i].ancestor = parent;
15566                 /* Step 3 */
15567                 for(v = parent->sdominates; v; v = next) {
15568                         struct sdom_block *u;
15569                         next = v->sdom_next;
15570                         unsdom_block(v);
15571                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15572                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15573                                 u->block : parent->block;
15574                 }
15575         }
15576 }
15577
15578 static void compute_spdom(struct compile_state *state, 
15579         struct basic_blocks *bb, struct sdom_block *sd)
15580 {
15581         int i;
15582         /* // step 2 
15583          *  for each v <= pred(w) {
15584          *      u = EVAL(v);
15585          *      if (semi[u] < semi[w] { 
15586          *              semi[w] = semi[u]; 
15587          *      } 
15588          * }
15589          * add w to bucket(vertex(semi[w]));
15590          * LINK(parent(w), w);
15591          *
15592          * // step 3
15593          * for each v <= bucket(parent(w)) {
15594          *      delete v from bucket(parent(w));
15595          *      u = EVAL(v);
15596          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15597          * }
15598          */
15599         for(i = bb->last_vertex; i >= 2; i--) {
15600                 struct sdom_block *u, *v, *parent, *next;
15601                 struct block_set *edge;
15602                 struct block *block;
15603                 block = sd[i].block;
15604                 parent = sd[i].parent;
15605                 /* Step 2 */
15606                 for(edge = block->edges; edge; edge = edge->next) {
15607                         v = &sd[edge->member->vertex];
15608                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15609                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15610                                 sd[i].sdom = u->sdom;
15611                         }
15612                 }
15613                 sdom_block(sd[i].sdom, &sd[i]);
15614                 sd[i].ancestor = parent;
15615                 /* Step 3 */
15616                 for(v = parent->sdominates; v; v = next) {
15617                         struct sdom_block *u;
15618                         next = v->sdom_next;
15619                         unsdom_block(v);
15620                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15621                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15622                                 u->block : parent->block;
15623                 }
15624         }
15625 }
15626
15627 static void compute_idom(struct compile_state *state, 
15628         struct basic_blocks *bb, struct sdom_block *sd)
15629 {
15630         int i;
15631         for(i = 2; i <= bb->last_vertex; i++) {
15632                 struct block *block;
15633                 block = sd[i].block;
15634                 if (block->idom->vertex != sd[i].sdom->vertex) {
15635                         block->idom = block->idom->idom;
15636                 }
15637                 idom_block(block->idom, block);
15638         }
15639         sd[1].block->idom = 0;
15640 }
15641
15642 static void compute_ipdom(struct compile_state *state, 
15643         struct basic_blocks *bb, struct sdom_block *sd)
15644 {
15645         int i;
15646         for(i = 2; i <= bb->last_vertex; i++) {
15647                 struct block *block;
15648                 block = sd[i].block;
15649                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15650                         block->ipdom = block->ipdom->ipdom;
15651                 }
15652                 ipdom_block(block->ipdom, block);
15653         }
15654         sd[1].block->ipdom = 0;
15655 }
15656
15657         /* Theorem 1:
15658          *   Every vertex of a flowgraph G = (V, E, r) except r has
15659          *   a unique immediate dominator.  
15660          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15661          *   rooted at r, called the dominator tree of G, such that 
15662          *   v dominates w if and only if v is a proper ancestor of w in
15663          *   the dominator tree.
15664          */
15665         /* Lemma 1:  
15666          *   If v and w are vertices of G such that v <= w,
15667          *   than any path from v to w must contain a common ancestor
15668          *   of v and w in T.
15669          */
15670         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15671         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15672         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15673         /* Theorem 2:
15674          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15675          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15676          */
15677         /* Theorem 3:
15678          *   Let w != r and let u be a vertex for which sdom(u) is 
15679          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15680          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15681          */
15682         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15683          *           Then v -> idom(w) or idom(w) -> idom(v)
15684          */
15685
15686 static void find_immediate_dominators(struct compile_state *state,
15687         struct basic_blocks *bb)
15688 {
15689         struct sdom_block *sd;
15690         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15691          *           vi > w for (1 <= i <= k - 1}
15692          */
15693         /* Theorem 4:
15694          *   For any vertex w != r.
15695          *   sdom(w) = min(
15696          *                 {v|(v,w) <= E  and v < w } U 
15697          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15698          */
15699         /* Corollary 1:
15700          *   Let w != r and let u be a vertex for which sdom(u) is 
15701          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15702          *   Then:
15703          *                   { sdom(w) if sdom(w) = sdom(u),
15704          *        idom(w) = {
15705          *                   { idom(u) otherwise
15706          */
15707         /* The algorithm consists of the following 4 steps.
15708          * Step 1.  Carry out a depth-first search of the problem graph.  
15709          *    Number the vertices from 1 to N as they are reached during
15710          *    the search.  Initialize the variables used in succeeding steps.
15711          * Step 2.  Compute the semidominators of all vertices by applying
15712          *    theorem 4.   Carry out the computation vertex by vertex in
15713          *    decreasing order by number.
15714          * Step 3.  Implicitly define the immediate dominator of each vertex
15715          *    by applying Corollary 1.
15716          * Step 4.  Explicitly define the immediate dominator of each vertex,
15717          *    carrying out the computation vertex by vertex in increasing order
15718          *    by number.
15719          */
15720         /* Step 1 initialize the basic block information */
15721         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15722         initialize_sdblock(sd, 0, bb->first_block, 0);
15723 #if 0
15724         sd[1].size  = 0;
15725         sd[1].label = 0;
15726         sd[1].sdom  = 0;
15727 #endif
15728         /* Step 2 compute the semidominators */
15729         /* Step 3 implicitly define the immediate dominator of each vertex */
15730         compute_sdom(state, bb, sd);
15731         /* Step 4 explicitly define the immediate dominator of each vertex */
15732         compute_idom(state, bb, sd);
15733         xfree(sd);
15734 }
15735
15736 static void find_post_dominators(struct compile_state *state,
15737         struct basic_blocks *bb)
15738 {
15739         struct sdom_block *sd;
15740         int vertex;
15741         /* Step 1 initialize the basic block information */
15742         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15743
15744         vertex = setup_spdblocks(state, bb, sd);
15745         if (vertex != bb->last_vertex) {
15746                 internal_error(state, 0, "missing %d blocks",
15747                         bb->last_vertex - vertex);
15748         }
15749
15750         /* Step 2 compute the semidominators */
15751         /* Step 3 implicitly define the immediate dominator of each vertex */
15752         compute_spdom(state, bb, sd);
15753         /* Step 4 explicitly define the immediate dominator of each vertex */
15754         compute_ipdom(state, bb, sd);
15755         xfree(sd);
15756 }
15757
15758
15759
15760 static void find_block_domf(struct compile_state *state, struct block *block)
15761 {
15762         struct block *child;
15763         struct block_set *user, *edge;
15764         if (block->domfrontier != 0) {
15765                 internal_error(state, block->first, "domfrontier present?");
15766         }
15767         for(user = block->idominates; user; user = user->next) {
15768                 child = user->member;
15769                 if (child->idom != block) {
15770                         internal_error(state, block->first, "bad idom");
15771                 }
15772                 find_block_domf(state, child);
15773         }
15774         for(edge = block->edges; edge; edge = edge->next) {
15775                 if (edge->member->idom != block) {
15776                         domf_block(block, edge->member);
15777                 }
15778         }
15779         for(user = block->idominates; user; user = user->next) {
15780                 struct block_set *frontier;
15781                 child = user->member;
15782                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15783                         if (frontier->member->idom != block) {
15784                                 domf_block(block, frontier->member);
15785                         }
15786                 }
15787         }
15788 }
15789
15790 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15791 {
15792         struct block *child;
15793         struct block_set *user;
15794         if (block->ipdomfrontier != 0) {
15795                 internal_error(state, block->first, "ipdomfrontier present?");
15796         }
15797         for(user = block->ipdominates; user; user = user->next) {
15798                 child = user->member;
15799                 if (child->ipdom != block) {
15800                         internal_error(state, block->first, "bad ipdom");
15801                 }
15802                 find_block_ipdomf(state, child);
15803         }
15804         for(user = block->use; user; user = user->next) {
15805                 if (user->member->ipdom != block) {
15806                         ipdomf_block(block, user->member);
15807                 }
15808         }
15809         for(user = block->ipdominates; user; user = user->next) {
15810                 struct block_set *frontier;
15811                 child = user->member;
15812                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15813                         if (frontier->member->ipdom != block) {
15814                                 ipdomf_block(block, frontier->member);
15815                         }
15816                 }
15817         }
15818 }
15819
15820 static void print_dominated(
15821         struct compile_state *state, struct block *block, void *arg)
15822 {
15823         struct block_set *user;
15824         FILE *fp = arg;
15825
15826         fprintf(fp, "%d:", block->vertex);
15827         for(user = block->idominates; user; user = user->next) {
15828                 fprintf(fp, " %d", user->member->vertex);
15829                 if (user->member->idom != block) {
15830                         internal_error(state, user->member->first, "bad idom");
15831                 }
15832         }
15833         fprintf(fp,"\n");
15834 }
15835
15836 static void print_dominated2(
15837         struct compile_state *state, FILE *fp, int depth, struct block *block)
15838 {
15839         struct block_set *user;
15840         struct triple *ins;
15841         struct occurance *ptr, *ptr2;
15842         const char *filename1, *filename2;
15843         int equal_filenames;
15844         int i;
15845         for(i = 0; i < depth; i++) {
15846                 fprintf(fp, "   ");
15847         }
15848         fprintf(fp, "%3d: %p (%p - %p) @", 
15849                 block->vertex, block, block->first, block->last);
15850         ins = block->first;
15851         while(ins != block->last && (ins->occurance->line == 0)) {
15852                 ins = ins->next;
15853         }
15854         ptr = ins->occurance;
15855         ptr2 = block->last->occurance;
15856         filename1 = ptr->filename? ptr->filename : "";
15857         filename2 = ptr2->filename? ptr2->filename : "";
15858         equal_filenames = (strcmp(filename1, filename2) == 0);
15859         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15860                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15861         } else if (equal_filenames) {
15862                 fprintf(fp, " %s:(%d - %d)",
15863                         ptr->filename, ptr->line, ptr2->line);
15864         } else {
15865                 fprintf(fp, " (%s:%d - %s:%d)",
15866                         ptr->filename, ptr->line,
15867                         ptr2->filename, ptr2->line);
15868         }
15869         fprintf(fp, "\n");
15870         for(user = block->idominates; user; user = user->next) {
15871                 print_dominated2(state, fp, depth + 1, user->member);
15872         }
15873 }
15874
15875 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15876 {
15877         fprintf(fp, "\ndominates\n");
15878         walk_blocks(state, bb, print_dominated, fp);
15879         fprintf(fp, "dominates\n");
15880         print_dominated2(state, fp, 0, bb->first_block);
15881 }
15882
15883
15884 static int print_frontiers(
15885         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15886 {
15887         struct block_set *user, *edge;
15888
15889         if (!block || (block->vertex != vertex + 1)) {
15890                 return vertex;
15891         }
15892         vertex += 1;
15893
15894         fprintf(fp, "%d:", block->vertex);
15895         for(user = block->domfrontier; user; user = user->next) {
15896                 fprintf(fp, " %d", user->member->vertex);
15897         }
15898         fprintf(fp, "\n");
15899         
15900         for(edge = block->edges; edge; edge = edge->next) {
15901                 vertex = print_frontiers(state, fp, edge->member, vertex);
15902         }
15903         return vertex;
15904 }
15905 static void print_dominance_frontiers(struct compile_state *state,
15906         FILE *fp, struct basic_blocks *bb)
15907 {
15908         fprintf(fp, "\ndominance frontiers\n");
15909         print_frontiers(state, fp, bb->first_block, 0);
15910         
15911 }
15912
15913 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15914 {
15915         /* Find the immediate dominators */
15916         find_immediate_dominators(state, bb);
15917         /* Find the dominance frontiers */
15918         find_block_domf(state, bb->first_block);
15919         /* If debuging print the print what I have just found */
15920         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15921                 print_dominators(state, state->dbgout, bb);
15922                 print_dominance_frontiers(state, state->dbgout, bb);
15923                 print_control_flow(state, state->dbgout, bb);
15924         }
15925 }
15926
15927
15928 static void print_ipdominated(
15929         struct compile_state *state, struct block *block, void *arg)
15930 {
15931         struct block_set *user;
15932         FILE *fp = arg;
15933
15934         fprintf(fp, "%d:", block->vertex);
15935         for(user = block->ipdominates; user; user = user->next) {
15936                 fprintf(fp, " %d", user->member->vertex);
15937                 if (user->member->ipdom != block) {
15938                         internal_error(state, user->member->first, "bad ipdom");
15939                 }
15940         }
15941         fprintf(fp, "\n");
15942 }
15943
15944 static void print_ipdominators(struct compile_state *state, FILE *fp,
15945         struct basic_blocks *bb)
15946 {
15947         fprintf(fp, "\nipdominates\n");
15948         walk_blocks(state, bb, print_ipdominated, fp);
15949 }
15950
15951 static int print_pfrontiers(
15952         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15953 {
15954         struct block_set *user;
15955
15956         if (!block || (block->vertex != vertex + 1)) {
15957                 return vertex;
15958         }
15959         vertex += 1;
15960
15961         fprintf(fp, "%d:", block->vertex);
15962         for(user = block->ipdomfrontier; user; user = user->next) {
15963                 fprintf(fp, " %d", user->member->vertex);
15964         }
15965         fprintf(fp, "\n");
15966         for(user = block->use; user; user = user->next) {
15967                 vertex = print_pfrontiers(state, fp, user->member, vertex);
15968         }
15969         return vertex;
15970 }
15971 static void print_ipdominance_frontiers(struct compile_state *state,
15972         FILE *fp, struct basic_blocks *bb)
15973 {
15974         fprintf(fp, "\nipdominance frontiers\n");
15975         print_pfrontiers(state, fp, bb->last_block, 0);
15976         
15977 }
15978
15979 static void analyze_ipdominators(struct compile_state *state,
15980         struct basic_blocks *bb)
15981 {
15982         /* Find the post dominators */
15983         find_post_dominators(state, bb);
15984         /* Find the control dependencies (post dominance frontiers) */
15985         find_block_ipdomf(state, bb->last_block);
15986         /* If debuging print the print what I have just found */
15987         if (state->compiler->debug & DEBUG_RDOMINATORS) {
15988                 print_ipdominators(state, state->dbgout, bb);
15989                 print_ipdominance_frontiers(state, state->dbgout, bb);
15990                 print_control_flow(state, state->dbgout, bb);
15991         }
15992 }
15993
15994 static int bdominates(struct compile_state *state,
15995         struct block *dom, struct block *sub)
15996 {
15997         while(sub && (sub != dom)) {
15998                 sub = sub->idom;
15999         }
16000         return sub == dom;
16001 }
16002
16003 static int tdominates(struct compile_state *state,
16004         struct triple *dom, struct triple *sub)
16005 {
16006         struct block *bdom, *bsub;
16007         int result;
16008         bdom = block_of_triple(state, dom);
16009         bsub = block_of_triple(state, sub);
16010         if (bdom != bsub) {
16011                 result = bdominates(state, bdom, bsub);
16012         } 
16013         else {
16014                 struct triple *ins;
16015                 if (!bdom || !bsub) {
16016                         internal_error(state, dom, "huh?");
16017                 }
16018                 ins = sub;
16019                 while((ins != bsub->first) && (ins != dom)) {
16020                         ins = ins->prev;
16021                 }
16022                 result = (ins == dom);
16023         }
16024         return result;
16025 }
16026
16027 static void analyze_basic_blocks(
16028         struct compile_state *state, struct basic_blocks *bb)
16029 {
16030         setup_basic_blocks(state, bb);
16031         analyze_idominators(state, bb);
16032         analyze_ipdominators(state, bb);
16033 }
16034
16035 static void insert_phi_operations(struct compile_state *state)
16036 {
16037         size_t size;
16038         struct triple *first;
16039         int *has_already, *work;
16040         struct block *work_list, **work_list_tail;
16041         int iter;
16042         struct triple *var, *vnext;
16043
16044         size = sizeof(int) * (state->bb.last_vertex + 1);
16045         has_already = xcmalloc(size, "has_already");
16046         work =        xcmalloc(size, "work");
16047         iter = 0;
16048
16049         first = state->first;
16050         for(var = first->next; var != first ; var = vnext) {
16051                 struct block *block;
16052                 struct triple_set *user, *unext;
16053                 vnext = var->next;
16054
16055                 if (!triple_is_auto_var(state, var) || !var->use) {
16056                         continue;
16057                 }
16058                         
16059                 iter += 1;
16060                 work_list = 0;
16061                 work_list_tail = &work_list;
16062                 for(user = var->use; user; user = unext) {
16063                         unext = user->next;
16064                         if (MISC(var, 0) == user->member) {
16065                                 continue;
16066                         }
16067                         if (user->member->op == OP_READ) {
16068                                 continue;
16069                         }
16070                         if (user->member->op != OP_WRITE) {
16071                                 internal_error(state, user->member, 
16072                                         "bad variable access");
16073                         }
16074                         block = user->member->u.block;
16075                         if (!block) {
16076                                 warning(state, user->member, "dead code");
16077                                 release_triple(state, user->member);
16078                                 continue;
16079                         }
16080                         if (work[block->vertex] >= iter) {
16081                                 continue;
16082                         }
16083                         work[block->vertex] = iter;
16084                         *work_list_tail = block;
16085                         block->work_next = 0;
16086                         work_list_tail = &block->work_next;
16087                 }
16088                 for(block = work_list; block; block = block->work_next) {
16089                         struct block_set *df;
16090                         for(df = block->domfrontier; df; df = df->next) {
16091                                 struct triple *phi;
16092                                 struct block *front;
16093                                 int in_edges;
16094                                 front = df->member;
16095
16096                                 if (has_already[front->vertex] >= iter) {
16097                                         continue;
16098                                 }
16099                                 /* Count how many edges flow into this block */
16100                                 in_edges = front->users;
16101                                 /* Insert a phi function for this variable */
16102                                 get_occurance(var->occurance);
16103                                 phi = alloc_triple(
16104                                         state, OP_PHI, var->type, -1, in_edges, 
16105                                         var->occurance);
16106                                 phi->u.block = front;
16107                                 MISC(phi, 0) = var;
16108                                 use_triple(var, phi);
16109 #if 1
16110                                 if (phi->rhs != in_edges) {
16111                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
16112                                                 phi->rhs, in_edges);
16113                                 }
16114 #endif
16115                                 /* Insert the phi functions immediately after the label */
16116                                 insert_triple(state, front->first->next, phi);
16117                                 if (front->first == front->last) {
16118                                         front->last = front->first->next;
16119                                 }
16120                                 has_already[front->vertex] = iter;
16121                                 transform_to_arch_instruction(state, phi);
16122
16123                                 /* If necessary plan to visit the basic block */
16124                                 if (work[front->vertex] >= iter) {
16125                                         continue;
16126                                 }
16127                                 work[front->vertex] = iter;
16128                                 *work_list_tail = front;
16129                                 front->work_next = 0;
16130                                 work_list_tail = &front->work_next;
16131                         }
16132                 }
16133         }
16134         xfree(has_already);
16135         xfree(work);
16136 }
16137
16138
16139 struct stack {
16140         struct triple_set *top;
16141         unsigned orig_id;
16142 };
16143
16144 static int count_auto_vars(struct compile_state *state)
16145 {
16146         struct triple *first, *ins;
16147         int auto_vars = 0;
16148         first = state->first;
16149         ins = first;
16150         do {
16151                 if (triple_is_auto_var(state, ins)) {
16152                         auto_vars += 1;
16153                 }
16154                 ins = ins->next;
16155         } while(ins != first);
16156         return auto_vars;
16157 }
16158
16159 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16160 {
16161         struct triple *first, *ins;
16162         int auto_vars = 0;
16163         first = state->first;
16164         ins = first;
16165         do {
16166                 if (triple_is_auto_var(state, ins)) {
16167                         auto_vars += 1;
16168                         stacks[auto_vars].orig_id = ins->id;
16169                         ins->id = auto_vars;
16170                 }
16171                 ins = ins->next;
16172         } while(ins != first);
16173 }
16174
16175 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16176 {
16177         struct triple *first, *ins;
16178         first = state->first;
16179         ins = first;
16180         do {
16181                 if (triple_is_auto_var(state, ins)) {
16182                         ins->id = stacks[ins->id].orig_id;
16183                 }
16184                 ins = ins->next;
16185         } while(ins != first);
16186 }
16187
16188 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16189 {
16190         struct triple_set *head;
16191         struct triple *top_val;
16192         top_val = 0;
16193         head = stacks[var->id].top;
16194         if (head) {
16195                 top_val = head->member;
16196         }
16197         return top_val;
16198 }
16199
16200 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16201 {
16202         struct triple_set *new;
16203         /* Append new to the head of the list,
16204          * it's the only sensible behavoir for a stack.
16205          */
16206         new = xcmalloc(sizeof(*new), "triple_set");
16207         new->member = val;
16208         new->next   = stacks[var->id].top;
16209         stacks[var->id].top = new;
16210 }
16211
16212 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16213 {
16214         struct triple_set *set, **ptr;
16215         ptr = &stacks[var->id].top;
16216         while(*ptr) {
16217                 set = *ptr;
16218                 if (set->member == oldval) {
16219                         *ptr = set->next;
16220                         xfree(set);
16221                         /* Only free one occurance from the stack */
16222                         return;
16223                 }
16224                 else {
16225                         ptr = &set->next;
16226                 }
16227         }
16228 }
16229
16230 /*
16231  * C(V)
16232  * S(V)
16233  */
16234 static void fixup_block_phi_variables(
16235         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16236 {
16237         struct block_set *set;
16238         struct triple *ptr;
16239         int edge;
16240         if (!parent || !block)
16241                 return;
16242         /* Find the edge I am coming in on */
16243         edge = 0;
16244         for(set = block->use; set; set = set->next, edge++) {
16245                 if (set->member == parent) {
16246                         break;
16247                 }
16248         }
16249         if (!set) {
16250                 internal_error(state, 0, "phi input is not on a control predecessor");
16251         }
16252         for(ptr = block->first; ; ptr = ptr->next) {
16253                 if (ptr->op == OP_PHI) {
16254                         struct triple *var, *val, **slot;
16255                         var = MISC(ptr, 0);
16256                         if (!var) {
16257                                 internal_error(state, ptr, "no var???");
16258                         }
16259                         /* Find the current value of the variable */
16260                         val = peek_triple(stacks, var);
16261                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16262                                 internal_error(state, val, "bad value in phi");
16263                         }
16264                         if (edge >= ptr->rhs) {
16265                                 internal_error(state, ptr, "edges > phi rhs");
16266                         }
16267                         slot = &RHS(ptr, edge);
16268                         if ((*slot != 0) && (*slot != val)) {
16269                                 internal_error(state, ptr, "phi already bound on this edge");
16270                         }
16271                         *slot = val;
16272                         use_triple(val, ptr);
16273                 }
16274                 if (ptr == block->last) {
16275                         break;
16276                 }
16277         }
16278 }
16279
16280
16281 static void rename_block_variables(
16282         struct compile_state *state, struct stack *stacks, struct block *block)
16283 {
16284         struct block_set *user, *edge;
16285         struct triple *ptr, *next, *last;
16286         int done;
16287         if (!block)
16288                 return;
16289         last = block->first;
16290         done = 0;
16291         for(ptr = block->first; !done; ptr = next) {
16292                 next = ptr->next;
16293                 if (ptr == block->last) {
16294                         done = 1;
16295                 }
16296                 /* RHS(A) */
16297                 if (ptr->op == OP_READ) {
16298                         struct triple *var, *val;
16299                         var = RHS(ptr, 0);
16300                         if (!triple_is_auto_var(state, var)) {
16301                                 internal_error(state, ptr, "read of non auto var!");
16302                         }
16303                         unuse_triple(var, ptr);
16304                         /* Find the current value of the variable */
16305                         val = peek_triple(stacks, var);
16306                         if (!val) {
16307                                 /* Let the optimizer at variables that are not initially
16308                                  * set.  But give it a bogus value so things seem to
16309                                  * work by accident.  This is useful for bitfields because
16310                                  * setting them always involves a read-modify-write.
16311                                  */
16312                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16313                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16314                                         val->u.cval = 0xdeadbeaf;
16315                                 } else {
16316                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16317                                 }
16318                         }
16319                         if (!val) {
16320                                 error(state, ptr, "variable used without being set");
16321                         }
16322                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16323                                 internal_error(state, val, "bad value in read");
16324                         }
16325                         propogate_use(state, ptr, val);
16326                         release_triple(state, ptr);
16327                         continue;
16328                 }
16329                 /* LHS(A) */
16330                 if (ptr->op == OP_WRITE) {
16331                         struct triple *var, *val, *tval;
16332                         var = MISC(ptr, 0);
16333                         if (!triple_is_auto_var(state, var)) {
16334                                 internal_error(state, ptr, "write to non auto var!");
16335                         }
16336                         tval = val = RHS(ptr, 0);
16337                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16338                                 triple_is_auto_var(state, val)) {
16339                                 internal_error(state, ptr, "bad value in write");
16340                         }
16341                         /* Insert a cast if the types differ */
16342                         if (!is_subset_type(ptr->type, val->type)) {
16343                                 if (val->op == OP_INTCONST) {
16344                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16345                                         tval->u.cval = val->u.cval;
16346                                 }
16347                                 else {
16348                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16349                                         use_triple(val, tval);
16350                                 }
16351                                 transform_to_arch_instruction(state, tval);
16352                                 unuse_triple(val, ptr);
16353                                 RHS(ptr, 0) = tval;
16354                                 use_triple(tval, ptr);
16355                         }
16356                         propogate_use(state, ptr, tval);
16357                         unuse_triple(var, ptr);
16358                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16359                         push_triple(stacks, var, tval);
16360                 }
16361                 if (ptr->op == OP_PHI) {
16362                         struct triple *var;
16363                         var = MISC(ptr, 0);
16364                         if (!triple_is_auto_var(state, var)) {
16365                                 internal_error(state, ptr, "phi references non auto var!");
16366                         }
16367                         /* Push OP_PHI onto a stack of variable uses */
16368                         push_triple(stacks, var, ptr);
16369                 }
16370                 last = ptr;
16371         }
16372         block->last = last;
16373
16374         /* Fixup PHI functions in the cf successors */
16375         for(edge = block->edges; edge; edge = edge->next) {
16376                 fixup_block_phi_variables(state, stacks, block, edge->member);
16377         }
16378         /* rename variables in the dominated nodes */
16379         for(user = block->idominates; user; user = user->next) {
16380                 rename_block_variables(state, stacks, user->member);
16381         }
16382         /* pop the renamed variable stack */
16383         last = block->first;
16384         done = 0;
16385         for(ptr = block->first; !done ; ptr = next) {
16386                 next = ptr->next;
16387                 if (ptr == block->last) {
16388                         done = 1;
16389                 }
16390                 if (ptr->op == OP_WRITE) {
16391                         struct triple *var;
16392                         var = MISC(ptr, 0);
16393                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16394                         pop_triple(stacks, var, RHS(ptr, 0));
16395                         release_triple(state, ptr);
16396                         continue;
16397                 }
16398                 if (ptr->op == OP_PHI) {
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, ptr);
16403                 }
16404                 last = ptr;
16405         }
16406         block->last = last;
16407 }
16408
16409 static void rename_variables(struct compile_state *state)
16410 {
16411         struct stack *stacks;
16412         int auto_vars;
16413
16414         /* Allocate stacks for the Variables */
16415         auto_vars = count_auto_vars(state);
16416         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16417
16418         /* Give each auto_var a stack */
16419         number_auto_vars(state, stacks);
16420
16421         /* Rename the variables */
16422         rename_block_variables(state, stacks, state->bb.first_block);
16423
16424         /* Remove the stacks from the auto_vars */
16425         restore_auto_vars(state, stacks);
16426         xfree(stacks);
16427 }
16428
16429 static void prune_block_variables(struct compile_state *state,
16430         struct block *block)
16431 {
16432         struct block_set *user;
16433         struct triple *next, *ptr;
16434         int done;
16435
16436         done = 0;
16437         for(ptr = block->first; !done; ptr = next) {
16438                 /* Be extremely careful I am deleting the list
16439                  * as I walk trhough it.
16440                  */
16441                 next = ptr->next;
16442                 if (ptr == block->last) {
16443                         done = 1;
16444                 }
16445                 if (triple_is_auto_var(state, ptr)) {
16446                         struct triple_set *user, *next;
16447                         for(user = ptr->use; user; user = next) {
16448                                 struct triple *use;
16449                                 next = user->next;
16450                                 use = user->member;
16451                                 if (MISC(ptr, 0) == user->member) {
16452                                         continue;
16453                                 }
16454                                 if (use->op != OP_PHI) {
16455                                         internal_error(state, use, "decl still used");
16456                                 }
16457                                 if (MISC(use, 0) != ptr) {
16458                                         internal_error(state, use, "bad phi use of decl");
16459                                 }
16460                                 unuse_triple(ptr, use);
16461                                 MISC(use, 0) = 0;
16462                         }
16463                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16464                                 /* Delete the adecl */
16465                                 release_triple(state, MISC(ptr, 0));
16466                                 /* And the piece */
16467                                 release_triple(state, ptr);
16468                         }
16469                         continue;
16470                 }
16471         }
16472         for(user = block->idominates; user; user = user->next) {
16473                 prune_block_variables(state, user->member);
16474         }
16475 }
16476
16477 struct phi_triple {
16478         struct triple *phi;
16479         unsigned orig_id;
16480         int alive;
16481 };
16482
16483 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16484 {
16485         struct triple **slot;
16486         int zrhs, i;
16487         if (live[phi->id].alive) {
16488                 return;
16489         }
16490         live[phi->id].alive = 1;
16491         zrhs = phi->rhs;
16492         slot = &RHS(phi, 0);
16493         for(i = 0; i < zrhs; i++) {
16494                 struct triple *used;
16495                 used = slot[i];
16496                 if (used && (used->op == OP_PHI)) {
16497                         keep_phi(state, live, used);
16498                 }
16499         }
16500 }
16501
16502 static void prune_unused_phis(struct compile_state *state)
16503 {
16504         struct triple *first, *phi;
16505         struct phi_triple *live;
16506         int phis, i;
16507         
16508         /* Find the first instruction */
16509         first = state->first;
16510
16511         /* Count how many phi functions I need to process */
16512         phis = 0;
16513         for(phi = first->next; phi != first; phi = phi->next) {
16514                 if (phi->op == OP_PHI) {
16515                         phis += 1;
16516                 }
16517         }
16518         
16519         /* Mark them all dead */
16520         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16521         phis = 0;
16522         for(phi = first->next; phi != first; phi = phi->next) {
16523                 if (phi->op != OP_PHI) {
16524                         continue;
16525                 }
16526                 live[phis].alive   = 0;
16527                 live[phis].orig_id = phi->id;
16528                 live[phis].phi     = phi;
16529                 phi->id = phis;
16530                 phis += 1;
16531         }
16532         
16533         /* Mark phis alive that are used by non phis */
16534         for(i = 0; i < phis; i++) {
16535                 struct triple_set *set;
16536                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16537                         if (set->member->op != OP_PHI) {
16538                                 keep_phi(state, live, live[i].phi);
16539                                 break;
16540                         }
16541                 }
16542         }
16543
16544         /* Delete the extraneous phis */
16545         for(i = 0; i < phis; i++) {
16546                 struct triple **slot;
16547                 int zrhs, j;
16548                 if (!live[i].alive) {
16549                         release_triple(state, live[i].phi);
16550                         continue;
16551                 }
16552                 phi = live[i].phi;
16553                 slot = &RHS(phi, 0);
16554                 zrhs = phi->rhs;
16555                 for(j = 0; j < zrhs; j++) {
16556                         if(!slot[j]) {
16557                                 struct triple *unknown;
16558                                 get_occurance(phi->occurance);
16559                                 unknown = flatten(state, state->global_pool,
16560                                         alloc_triple(state, OP_UNKNOWNVAL,
16561                                                 phi->type, 0, 0, phi->occurance));
16562                                 slot[j] = unknown;
16563                                 use_triple(unknown, phi);
16564                                 transform_to_arch_instruction(state, unknown);
16565 #if 0                           
16566                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16567 #endif
16568                         }
16569                 }
16570         }
16571         xfree(live);
16572 }
16573
16574 static void transform_to_ssa_form(struct compile_state *state)
16575 {
16576         insert_phi_operations(state);
16577         rename_variables(state);
16578
16579         prune_block_variables(state, state->bb.first_block);
16580         prune_unused_phis(state);
16581
16582         print_blocks(state, __func__, state->dbgout);
16583 }
16584
16585
16586 static void clear_vertex(
16587         struct compile_state *state, struct block *block, void *arg)
16588 {
16589         /* Clear the current blocks vertex and the vertex of all
16590          * of the current blocks neighbors in case there are malformed
16591          * blocks with now instructions at this point.
16592          */
16593         struct block_set *user, *edge;
16594         block->vertex = 0;
16595         for(edge = block->edges; edge; edge = edge->next) {
16596                 edge->member->vertex = 0;
16597         }
16598         for(user = block->use; user; user = user->next) {
16599                 user->member->vertex = 0;
16600         }
16601 }
16602
16603 static void mark_live_block(
16604         struct compile_state *state, struct block *block, int *next_vertex)
16605 {
16606         /* See if this is a block that has not been marked */
16607         if (block->vertex != 0) {
16608                 return;
16609         }
16610         block->vertex = *next_vertex;
16611         *next_vertex += 1;
16612         if (triple_is_branch(state, block->last)) {
16613                 struct triple **targ;
16614                 targ = triple_edge_targ(state, block->last, 0);
16615                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16616                         if (!*targ) {
16617                                 continue;
16618                         }
16619                         if (!triple_stores_block(state, *targ)) {
16620                                 internal_error(state, 0, "bad targ");
16621                         }
16622                         mark_live_block(state, (*targ)->u.block, next_vertex);
16623                 }
16624                 /* Ensure the last block of a function remains alive */
16625                 if (triple_is_call(state, block->last)) {
16626                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16627                 }
16628         }
16629         else if (block->last->next != state->first) {
16630                 struct triple *ins;
16631                 ins = block->last->next;
16632                 if (!triple_stores_block(state, ins)) {
16633                         internal_error(state, 0, "bad block start");
16634                 }
16635                 mark_live_block(state, ins->u.block, next_vertex);
16636         }
16637 }
16638
16639 static void transform_from_ssa_form(struct compile_state *state)
16640 {
16641         /* To get out of ssa form we insert moves on the incoming
16642          * edges to blocks containting phi functions.
16643          */
16644         struct triple *first;
16645         struct triple *phi, *var, *next;
16646         int next_vertex;
16647
16648         /* Walk the control flow to see which blocks remain alive */
16649         walk_blocks(state, &state->bb, clear_vertex, 0);
16650         next_vertex = 1;
16651         mark_live_block(state, state->bb.first_block, &next_vertex);
16652
16653         /* Walk all of the operations to find the phi functions */
16654         first = state->first;
16655         for(phi = first->next; phi != first ; phi = next) {
16656                 struct block_set *set;
16657                 struct block *block;
16658                 struct triple **slot;
16659                 struct triple *var;
16660                 struct triple_set *use, *use_next;
16661                 int edge, writers, readers;
16662                 next = phi->next;
16663                 if (phi->op != OP_PHI) {
16664                         continue;
16665                 }
16666
16667                 block = phi->u.block;
16668                 slot  = &RHS(phi, 0);
16669
16670                 /* If this phi is in a dead block just forget it */
16671                 if (block->vertex == 0) {
16672                         release_triple(state, phi);
16673                         continue;
16674                 }
16675
16676                 /* Forget uses from code in dead blocks */
16677                 for(use = phi->use; use; use = use_next) {
16678                         struct block *ublock;
16679                         struct triple **expr;
16680                         use_next = use->next;
16681                         ublock = block_of_triple(state, use->member);
16682                         if ((use->member == phi) || (ublock->vertex != 0)) {
16683                                 continue;
16684                         }
16685                         expr = triple_rhs(state, use->member, 0);
16686                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16687                                 if (*expr == phi) {
16688                                         *expr = 0;
16689                                 }
16690                         }
16691                         unuse_triple(phi, use->member);
16692                 }
16693                 /* A variable to replace the phi function */
16694                 if (registers_of(state, phi->type) != 1) {
16695                         internal_error(state, phi, "phi->type does not fit in a single register!");
16696                 }
16697                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16698                 var = var->next; /* point at the var */
16699                         
16700                 /* Replaces use of phi with var */
16701                 propogate_use(state, phi, var);
16702
16703                 /* Count the readers */
16704                 readers = 0;
16705                 for(use = var->use; use; use = use->next) {
16706                         if (use->member != MISC(var, 0)) {
16707                                 readers++;
16708                         }
16709                 }
16710
16711                 /* Walk all of the incoming edges/blocks and insert moves.
16712                  */
16713                 writers = 0;
16714                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16715                         struct block *eblock, *vblock;
16716                         struct triple *move;
16717                         struct triple *val, *base;
16718                         eblock = set->member;
16719                         val = slot[edge];
16720                         slot[edge] = 0;
16721                         unuse_triple(val, phi);
16722                         vblock = block_of_triple(state, val);
16723
16724                         /* If we don't have a value that belongs in an OP_WRITE
16725                          * continue on.
16726                          */
16727                         if (!val || (val == &unknown_triple) || (val == phi)
16728                                 || (vblock && (vblock->vertex == 0))) {
16729                                 continue;
16730                         }
16731                         /* If the value should never occur error */
16732                         if (!vblock) {
16733                                 internal_error(state, val, "no vblock?");
16734                                 continue;
16735                         }
16736
16737                         /* If the value occurs in a dead block see if a replacement
16738                          * block can be found.
16739                          */
16740                         while(eblock && (eblock->vertex == 0)) {
16741                                 eblock = eblock->idom;
16742                         }
16743                         /* If not continue on with the next value. */
16744                         if (!eblock || (eblock->vertex == 0)) {
16745                                 continue;
16746                         }
16747
16748                         /* If we have an empty incoming block ignore it. */
16749                         if (!eblock->first) {
16750                                 internal_error(state, 0, "empty block?");
16751                         }
16752                         
16753                         /* Make certain the write is placed in the edge block... */
16754                         /* Walk through the edge block backwards to find an
16755                          * appropriate location for the OP_WRITE.
16756                          */
16757                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16758                                 struct triple **expr;
16759                                 if (base->op == OP_PIECE) {
16760                                         base = MISC(base, 0);
16761                                 }
16762                                 if ((base == var) || (base == val)) {
16763                                         goto out;
16764                                 }
16765                                 expr = triple_lhs(state, base, 0);
16766                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16767                                         if ((*expr) == val) {
16768                                                 goto out;
16769                                         }
16770                                 }
16771                                 expr = triple_rhs(state, base, 0);
16772                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16773                                         if ((*expr) == var) {
16774                                                 goto out;
16775                                         }
16776                                 }
16777                         }
16778                 out:
16779                         if (triple_is_branch(state, base)) {
16780                                 internal_error(state, base,
16781                                         "Could not insert write to phi");
16782                         }
16783                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16784                         use_triple(val, move);
16785                         use_triple(var, move);
16786                         writers++;
16787                 }
16788                 if (!writers && readers) {
16789                         internal_error(state, var, "no value written to in use phi?");
16790                 }
16791                 /* If var is not used free it */
16792                 if (!writers) {
16793                         release_triple(state, MISC(var, 0));
16794                         release_triple(state, var);
16795                 }
16796                 /* Release the phi function */
16797                 release_triple(state, phi);
16798         }
16799         
16800         /* Walk all of the operations to find the adecls */
16801         for(var = first->next; var != first ; var = var->next) {
16802                 struct triple_set *use, *use_next;
16803                 if (!triple_is_auto_var(state, var)) {
16804                         continue;
16805                 }
16806
16807                 /* Walk through all of the rhs uses of var and
16808                  * replace them with read of var.
16809                  */
16810                 for(use = var->use; use; use = use_next) {
16811                         struct triple *read, *user;
16812                         struct triple **slot;
16813                         int zrhs, i, used;
16814                         use_next = use->next;
16815                         user = use->member;
16816                         
16817                         /* Generate a read of var */
16818                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16819                         use_triple(var, read);
16820
16821                         /* Find the rhs uses and see if they need to be replaced */
16822                         used = 0;
16823                         zrhs = user->rhs;
16824                         slot = &RHS(user, 0);
16825                         for(i = 0; i < zrhs; i++) {
16826                                 if (slot[i] == var) {
16827                                         slot[i] = read;
16828                                         used = 1;
16829                                 }
16830                         }
16831                         /* If we did use it cleanup the uses */
16832                         if (used) {
16833                                 unuse_triple(var, user);
16834                                 use_triple(read, user);
16835                         } 
16836                         /* If we didn't use it release the extra triple */
16837                         else {
16838                                 release_triple(state, read);
16839                         }
16840                 }
16841         }
16842 }
16843
16844 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16845         FILE *fp = state->dbgout; \
16846         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16847         } 
16848
16849 static void rebuild_ssa_form(struct compile_state *state)
16850 {
16851 HI();
16852         transform_from_ssa_form(state);
16853 HI();
16854         state->bb.first = state->first;
16855         free_basic_blocks(state, &state->bb);
16856         analyze_basic_blocks(state, &state->bb);
16857 HI();
16858         insert_phi_operations(state);
16859 HI();
16860         rename_variables(state);
16861 HI();
16862         
16863         prune_block_variables(state, state->bb.first_block);
16864 HI();
16865         prune_unused_phis(state);
16866 HI();
16867 }
16868 #undef HI
16869
16870 /* 
16871  * Register conflict resolution
16872  * =========================================================
16873  */
16874
16875 static struct reg_info find_def_color(
16876         struct compile_state *state, struct triple *def)
16877 {
16878         struct triple_set *set;
16879         struct reg_info info;
16880         info.reg = REG_UNSET;
16881         info.regcm = 0;
16882         if (!triple_is_def(state, def)) {
16883                 return info;
16884         }
16885         info = arch_reg_lhs(state, def, 0);
16886         if (info.reg >= MAX_REGISTERS) {
16887                 info.reg = REG_UNSET;
16888         }
16889         for(set = def->use; set; set = set->next) {
16890                 struct reg_info tinfo;
16891                 int i;
16892                 i = find_rhs_use(state, set->member, def);
16893                 if (i < 0) {
16894                         continue;
16895                 }
16896                 tinfo = arch_reg_rhs(state, set->member, i);
16897                 if (tinfo.reg >= MAX_REGISTERS) {
16898                         tinfo.reg = REG_UNSET;
16899                 }
16900                 if ((tinfo.reg != REG_UNSET) && 
16901                         (info.reg != REG_UNSET) &&
16902                         (tinfo.reg != info.reg)) {
16903                         internal_error(state, def, "register conflict");
16904                 }
16905                 if ((info.regcm & tinfo.regcm) == 0) {
16906                         internal_error(state, def, "regcm conflict %x & %x == 0",
16907                                 info.regcm, tinfo.regcm);
16908                 }
16909                 if (info.reg == REG_UNSET) {
16910                         info.reg = tinfo.reg;
16911                 }
16912                 info.regcm &= tinfo.regcm;
16913         }
16914         if (info.reg >= MAX_REGISTERS) {
16915                 internal_error(state, def, "register out of range");
16916         }
16917         return info;
16918 }
16919
16920 static struct reg_info find_lhs_pre_color(
16921         struct compile_state *state, struct triple *ins, int index)
16922 {
16923         struct reg_info info;
16924         int zlhs, zrhs, i;
16925         zrhs = ins->rhs;
16926         zlhs = ins->lhs;
16927         if (!zlhs && triple_is_def(state, ins)) {
16928                 zlhs = 1;
16929         }
16930         if (index >= zlhs) {
16931                 internal_error(state, ins, "Bad lhs %d", index);
16932         }
16933         info = arch_reg_lhs(state, ins, index);
16934         for(i = 0; i < zrhs; i++) {
16935                 struct reg_info rinfo;
16936                 rinfo = arch_reg_rhs(state, ins, i);
16937                 if ((info.reg == rinfo.reg) &&
16938                         (rinfo.reg >= MAX_REGISTERS)) {
16939                         struct reg_info tinfo;
16940                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16941                         info.reg = tinfo.reg;
16942                         info.regcm &= tinfo.regcm;
16943                         break;
16944                 }
16945         }
16946         if (info.reg >= MAX_REGISTERS) {
16947                 info.reg = REG_UNSET;
16948         }
16949         return info;
16950 }
16951
16952 static struct reg_info find_rhs_post_color(
16953         struct compile_state *state, struct triple *ins, int index);
16954
16955 static struct reg_info find_lhs_post_color(
16956         struct compile_state *state, struct triple *ins, int index)
16957 {
16958         struct triple_set *set;
16959         struct reg_info info;
16960         struct triple *lhs;
16961 #if DEBUG_TRIPLE_COLOR
16962         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
16963                 ins, index);
16964 #endif
16965         if ((index == 0) && triple_is_def(state, ins)) {
16966                 lhs = ins;
16967         }
16968         else if (index < ins->lhs) {
16969                 lhs = LHS(ins, index);
16970         }
16971         else {
16972                 internal_error(state, ins, "Bad lhs %d", index);
16973                 lhs = 0;
16974         }
16975         info = arch_reg_lhs(state, ins, index);
16976         if (info.reg >= MAX_REGISTERS) {
16977                 info.reg = REG_UNSET;
16978         }
16979         for(set = lhs->use; set; set = set->next) {
16980                 struct reg_info rinfo;
16981                 struct triple *user;
16982                 int zrhs, i;
16983                 user = set->member;
16984                 zrhs = user->rhs;
16985                 for(i = 0; i < zrhs; i++) {
16986                         if (RHS(user, i) != lhs) {
16987                                 continue;
16988                         }
16989                         rinfo = find_rhs_post_color(state, user, i);
16990                         if ((info.reg != REG_UNSET) &&
16991                                 (rinfo.reg != REG_UNSET) &&
16992                                 (info.reg != rinfo.reg)) {
16993                                 internal_error(state, ins, "register conflict");
16994                         }
16995                         if ((info.regcm & rinfo.regcm) == 0) {
16996                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
16997                                         info.regcm, rinfo.regcm);
16998                         }
16999                         if (info.reg == REG_UNSET) {
17000                                 info.reg = rinfo.reg;
17001                         }
17002                         info.regcm &= rinfo.regcm;
17003                 }
17004         }
17005 #if DEBUG_TRIPLE_COLOR
17006         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
17007                 ins, index, info.reg, info.regcm);
17008 #endif
17009         return info;
17010 }
17011
17012 static struct reg_info find_rhs_post_color(
17013         struct compile_state *state, struct triple *ins, int index)
17014 {
17015         struct reg_info info, rinfo;
17016         int zlhs, i;
17017 #if DEBUG_TRIPLE_COLOR
17018         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
17019                 ins, index);
17020 #endif
17021         rinfo = arch_reg_rhs(state, ins, index);
17022         zlhs = ins->lhs;
17023         if (!zlhs && triple_is_def(state, ins)) {
17024                 zlhs = 1;
17025         }
17026         info = rinfo;
17027         if (info.reg >= MAX_REGISTERS) {
17028                 info.reg = REG_UNSET;
17029         }
17030         for(i = 0; i < zlhs; i++) {
17031                 struct reg_info linfo;
17032                 linfo = arch_reg_lhs(state, ins, i);
17033                 if ((linfo.reg == rinfo.reg) &&
17034                         (linfo.reg >= MAX_REGISTERS)) {
17035                         struct reg_info tinfo;
17036                         tinfo = find_lhs_post_color(state, ins, i);
17037                         if (tinfo.reg >= MAX_REGISTERS) {
17038                                 tinfo.reg = REG_UNSET;
17039                         }
17040                         info.regcm &= linfo.regcm;
17041                         info.regcm &= tinfo.regcm;
17042                         if (info.reg != REG_UNSET) {
17043                                 internal_error(state, ins, "register conflict");
17044                         }
17045                         if (info.regcm == 0) {
17046                                 internal_error(state, ins, "regcm conflict");
17047                         }
17048                         info.reg = tinfo.reg;
17049                 }
17050         }
17051 #if DEBUG_TRIPLE_COLOR
17052         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
17053                 ins, index, info.reg, info.regcm);
17054 #endif
17055         return info;
17056 }
17057
17058 static struct reg_info find_lhs_color(
17059         struct compile_state *state, struct triple *ins, int index)
17060 {
17061         struct reg_info pre, post, info;
17062 #if DEBUG_TRIPLE_COLOR
17063         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
17064                 ins, index);
17065 #endif
17066         pre = find_lhs_pre_color(state, ins, index);
17067         post = find_lhs_post_color(state, ins, index);
17068         if ((pre.reg != post.reg) &&
17069                 (pre.reg != REG_UNSET) &&
17070                 (post.reg != REG_UNSET)) {
17071                 internal_error(state, ins, "register conflict");
17072         }
17073         info.regcm = pre.regcm & post.regcm;
17074         info.reg = pre.reg;
17075         if (info.reg == REG_UNSET) {
17076                 info.reg = post.reg;
17077         }
17078 #if DEBUG_TRIPLE_COLOR
17079         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
17080                 ins, index, info.reg, info.regcm,
17081                 pre.reg, pre.regcm, post.reg, post.regcm);
17082 #endif
17083         return info;
17084 }
17085
17086 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
17087 {
17088         struct triple_set *entry, *next;
17089         struct triple *out;
17090         struct reg_info info, rinfo;
17091
17092         info = arch_reg_lhs(state, ins, 0);
17093         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
17094         use_triple(RHS(out, 0), out);
17095         /* Get the users of ins to use out instead */
17096         for(entry = ins->use; entry; entry = next) {
17097                 int i;
17098                 next = entry->next;
17099                 if (entry->member == out) {
17100                         continue;
17101                 }
17102                 i = find_rhs_use(state, entry->member, ins);
17103                 if (i < 0) {
17104                         continue;
17105                 }
17106                 rinfo = arch_reg_rhs(state, entry->member, i);
17107                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
17108                         continue;
17109                 }
17110                 replace_rhs_use(state, ins, out, entry->member);
17111         }
17112         transform_to_arch_instruction(state, out);
17113         return out;
17114 }
17115
17116 static struct triple *typed_pre_copy(
17117         struct compile_state *state, struct type *type, struct triple *ins, int index)
17118 {
17119         /* Carefully insert enough operations so that I can
17120          * enter any operation with a GPR32.
17121          */
17122         struct triple *in;
17123         struct triple **expr;
17124         unsigned classes;
17125         struct reg_info info;
17126         int op;
17127         if (ins->op == OP_PHI) {
17128                 internal_error(state, ins, "pre_copy on a phi?");
17129         }
17130         classes = arch_type_to_regcm(state, type);
17131         info = arch_reg_rhs(state, ins, index);
17132         expr = &RHS(ins, index);
17133         if ((info.regcm & classes) == 0) {
17134                 FILE *fp = state->errout;
17135                 fprintf(fp, "src_type: ");
17136                 name_of(fp, ins->type);
17137                 fprintf(fp, "\ndst_type: ");
17138                 name_of(fp, type);
17139                 fprintf(fp, "\n");
17140                 internal_error(state, ins, "pre_copy with no register classes");
17141         }
17142         op = OP_COPY;
17143         if (!equiv_types(type, (*expr)->type)) {
17144                 op = OP_CONVERT;
17145         }
17146         in = pre_triple(state, ins, op, type, *expr, 0);
17147         unuse_triple(*expr, ins);
17148         *expr = in;
17149         use_triple(RHS(in, 0), in);
17150         use_triple(in, ins);
17151         transform_to_arch_instruction(state, in);
17152         return in;
17153         
17154 }
17155 static struct triple *pre_copy(
17156         struct compile_state *state, struct triple *ins, int index)
17157 {
17158         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17159 }
17160
17161
17162 static void insert_copies_to_phi(struct compile_state *state)
17163 {
17164         /* To get out of ssa form we insert moves on the incoming
17165          * edges to blocks containting phi functions.
17166          */
17167         struct triple *first;
17168         struct triple *phi;
17169
17170         /* Walk all of the operations to find the phi functions */
17171         first = state->first;
17172         for(phi = first->next; phi != first ; phi = phi->next) {
17173                 struct block_set *set;
17174                 struct block *block;
17175                 struct triple **slot, *copy;
17176                 int edge;
17177                 if (phi->op != OP_PHI) {
17178                         continue;
17179                 }
17180                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17181                 block = phi->u.block;
17182                 slot  = &RHS(phi, 0);
17183                 /* Phi's that feed into mandatory live range joins
17184                  * cause nasty complications.  Insert a copy of
17185                  * the phi value so I never have to deal with
17186                  * that in the rest of the code.
17187                  */
17188                 copy = post_copy(state, phi);
17189                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17190                 /* Walk all of the incoming edges/blocks and insert moves.
17191                  */
17192                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17193                         struct block *eblock;
17194                         struct triple *move;
17195                         struct triple *val;
17196                         struct triple *ptr;
17197                         eblock = set->member;
17198                         val = slot[edge];
17199
17200                         if (val == phi) {
17201                                 continue;
17202                         }
17203
17204                         get_occurance(val->occurance);
17205                         move = build_triple(state, OP_COPY, val->type, val, 0,
17206                                 val->occurance);
17207                         move->u.block = eblock;
17208                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17209                         use_triple(val, move);
17210                         
17211                         slot[edge] = move;
17212                         unuse_triple(val, phi);
17213                         use_triple(move, phi);
17214
17215                         /* Walk up the dominator tree until I have found the appropriate block */
17216                         while(eblock && !tdominates(state, val, eblock->last)) {
17217                                 eblock = eblock->idom;
17218                         }
17219                         if (!eblock) {
17220                                 internal_error(state, phi, "Cannot find block dominated by %p",
17221                                         val);
17222                         }
17223
17224                         /* Walk through the block backwards to find
17225                          * an appropriate location for the OP_COPY.
17226                          */
17227                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17228                                 struct triple **expr;
17229                                 if (ptr->op == OP_PIECE) {
17230                                         ptr = MISC(ptr, 0);
17231                                 }
17232                                 if ((ptr == phi) || (ptr == val)) {
17233                                         goto out;
17234                                 }
17235                                 expr = triple_lhs(state, ptr, 0);
17236                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17237                                         if ((*expr) == val) {
17238                                                 goto out;
17239                                         }
17240                                 }
17241                                 expr = triple_rhs(state, ptr, 0);
17242                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17243                                         if ((*expr) == phi) {
17244                                                 goto out;
17245                                         }
17246                                 }
17247                         }
17248                 out:
17249                         if (triple_is_branch(state, ptr)) {
17250                                 internal_error(state, ptr,
17251                                         "Could not insert write to phi");
17252                         }
17253                         insert_triple(state, after_lhs(state, ptr), move);
17254                         if (eblock->last == after_lhs(state, ptr)->prev) {
17255                                 eblock->last = move;
17256                         }
17257                         transform_to_arch_instruction(state, move);
17258                 }
17259         }
17260         print_blocks(state, __func__, state->dbgout);
17261 }
17262
17263 struct triple_reg_set;
17264 struct reg_block;
17265
17266
17267 static int do_triple_set(struct triple_reg_set **head, 
17268         struct triple *member, struct triple *new_member)
17269 {
17270         struct triple_reg_set **ptr, *new;
17271         if (!member)
17272                 return 0;
17273         ptr = head;
17274         while(*ptr) {
17275                 if ((*ptr)->member == member) {
17276                         return 0;
17277                 }
17278                 ptr = &(*ptr)->next;
17279         }
17280         new = xcmalloc(sizeof(*new), "triple_set");
17281         new->member = member;
17282         new->new    = new_member;
17283         new->next   = *head;
17284         *head       = new;
17285         return 1;
17286 }
17287
17288 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17289 {
17290         struct triple_reg_set *entry, **ptr;
17291         ptr = head;
17292         while(*ptr) {
17293                 entry = *ptr;
17294                 if (entry->member == member) {
17295                         *ptr = entry->next;
17296                         xfree(entry);
17297                         return;
17298                 }
17299                 else {
17300                         ptr = &entry->next;
17301                 }
17302         }
17303 }
17304
17305 static int in_triple(struct reg_block *rb, struct triple *in)
17306 {
17307         return do_triple_set(&rb->in, in, 0);
17308 }
17309 static void unin_triple(struct reg_block *rb, struct triple *unin)
17310 {
17311         do_triple_unset(&rb->in, unin);
17312 }
17313
17314 static int out_triple(struct reg_block *rb, struct triple *out)
17315 {
17316         return do_triple_set(&rb->out, out, 0);
17317 }
17318 static void unout_triple(struct reg_block *rb, struct triple *unout)
17319 {
17320         do_triple_unset(&rb->out, unout);
17321 }
17322
17323 static int initialize_regblock(struct reg_block *blocks,
17324         struct block *block, int vertex)
17325 {
17326         struct block_set *user;
17327         if (!block || (blocks[block->vertex].block == block)) {
17328                 return vertex;
17329         }
17330         vertex += 1;
17331         /* Renumber the blocks in a convinient fashion */
17332         block->vertex = vertex;
17333         blocks[vertex].block    = block;
17334         blocks[vertex].vertex   = vertex;
17335         for(user = block->use; user; user = user->next) {
17336                 vertex = initialize_regblock(blocks, user->member, vertex);
17337         }
17338         return vertex;
17339 }
17340
17341 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17342 {
17343 /* Part to piece is a best attempt and it cannot be correct all by
17344  * itself.  If various values are read as different sizes in different
17345  * parts of the code this function cannot work.  Or rather it cannot
17346  * work in conjunction with compute_variable_liftimes.  As the
17347  * analysis will get confused.
17348  */
17349         struct triple *base;
17350         unsigned reg;
17351         if (!is_lvalue(state, ins)) {
17352                 return ins;
17353         }
17354         base = 0;
17355         reg = 0;
17356         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17357                 base = MISC(ins, 0);
17358                 switch(ins->op) {
17359                 case OP_INDEX:
17360                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17361                         break;
17362                 case OP_DOT:
17363                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17364                         break;
17365                 default:
17366                         internal_error(state, ins, "unhandled part");
17367                         break;
17368                 }
17369                 ins = base;
17370         }
17371         if (base) {
17372                 if (reg > base->lhs) {
17373                         internal_error(state, base, "part out of range?");
17374                 }
17375                 ins = LHS(base, reg);
17376         }
17377         return ins;
17378 }
17379
17380 static int this_def(struct compile_state *state, 
17381         struct triple *ins, struct triple *other)
17382 {
17383         if (ins == other) {
17384                 return 1;
17385         }
17386         if (ins->op == OP_WRITE) {
17387                 ins = part_to_piece(state, MISC(ins, 0));
17388         }
17389         return ins == other;
17390 }
17391
17392 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17393         struct reg_block *rb, struct block *suc)
17394 {
17395         /* Read the conditional input set of a successor block
17396          * (i.e. the input to the phi nodes) and place it in the
17397          * current blocks output set.
17398          */
17399         struct block_set *set;
17400         struct triple *ptr;
17401         int edge;
17402         int done, change;
17403         change = 0;
17404         /* Find the edge I am coming in on */
17405         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17406                 if (set->member == rb->block) {
17407                         break;
17408                 }
17409         }
17410         if (!set) {
17411                 internal_error(state, 0, "Not coming on a control edge?");
17412         }
17413         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17414                 struct triple **slot, *expr, *ptr2;
17415                 int out_change, done2;
17416                 done = (ptr == suc->last);
17417                 if (ptr->op != OP_PHI) {
17418                         continue;
17419                 }
17420                 slot = &RHS(ptr, 0);
17421                 expr = slot[edge];
17422                 out_change = out_triple(rb, expr);
17423                 if (!out_change) {
17424                         continue;
17425                 }
17426                 /* If we don't define the variable also plast it
17427                  * in the current blocks input set.
17428                  */
17429                 ptr2 = rb->block->first;
17430                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17431                         if (this_def(state, ptr2, expr)) {
17432                                 break;
17433                         }
17434                         done2 = (ptr2 == rb->block->last);
17435                 }
17436                 if (!done2) {
17437                         continue;
17438                 }
17439                 change |= in_triple(rb, expr);
17440         }
17441         return change;
17442 }
17443
17444 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17445         struct reg_block *rb, struct block *suc)
17446 {
17447         struct triple_reg_set *in_set;
17448         int change;
17449         change = 0;
17450         /* Read the input set of a successor block
17451          * and place it in the current blocks output set.
17452          */
17453         in_set = blocks[suc->vertex].in;
17454         for(; in_set; in_set = in_set->next) {
17455                 int out_change, done;
17456                 struct triple *first, *last, *ptr;
17457                 out_change = out_triple(rb, in_set->member);
17458                 if (!out_change) {
17459                         continue;
17460                 }
17461                 /* If we don't define the variable also place it
17462                  * in the current blocks input set.
17463                  */
17464                 first = rb->block->first;
17465                 last = rb->block->last;
17466                 done = 0;
17467                 for(ptr = first; !done; ptr = ptr->next) {
17468                         if (this_def(state, ptr, in_set->member)) {
17469                                 break;
17470                         }
17471                         done = (ptr == last);
17472                 }
17473                 if (!done) {
17474                         continue;
17475                 }
17476                 change |= in_triple(rb, in_set->member);
17477         }
17478         change |= phi_in(state, blocks, rb, suc);
17479         return change;
17480 }
17481
17482 static int use_in(struct compile_state *state, struct reg_block *rb)
17483 {
17484         /* Find the variables we use but don't define and add
17485          * it to the current blocks input set.
17486          */
17487 #warning "FIXME is this O(N^2) algorithm bad?"
17488         struct block *block;
17489         struct triple *ptr;
17490         int done;
17491         int change;
17492         block = rb->block;
17493         change = 0;
17494         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17495                 struct triple **expr;
17496                 done = (ptr == block->first);
17497                 /* The variable a phi function uses depends on the
17498                  * control flow, and is handled in phi_in, not
17499                  * here.
17500                  */
17501                 if (ptr->op == OP_PHI) {
17502                         continue;
17503                 }
17504                 expr = triple_rhs(state, ptr, 0);
17505                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17506                         struct triple *rhs, *test;
17507                         int tdone;
17508                         rhs = part_to_piece(state, *expr);
17509                         if (!rhs) {
17510                                 continue;
17511                         }
17512
17513                         /* See if rhs is defined in this block.
17514                          * A write counts as a definition.
17515                          */
17516                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17517                                 tdone = (test == block->first);
17518                                 if (this_def(state, test, rhs)) {
17519                                         rhs = 0;
17520                                         break;
17521                                 }
17522                         }
17523                         /* If I still have a valid rhs add it to in */
17524                         change |= in_triple(rb, rhs);
17525                 }
17526         }
17527         return change;
17528 }
17529
17530 static struct reg_block *compute_variable_lifetimes(
17531         struct compile_state *state, struct basic_blocks *bb)
17532 {
17533         struct reg_block *blocks;
17534         int change;
17535         blocks = xcmalloc(
17536                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17537         initialize_regblock(blocks, bb->last_block, 0);
17538         do {
17539                 int i;
17540                 change = 0;
17541                 for(i = 1; i <= bb->last_vertex; i++) {
17542                         struct block_set *edge;
17543                         struct reg_block *rb;
17544                         rb = &blocks[i];
17545                         /* Add the all successor's input set to in */
17546                         for(edge = rb->block->edges; edge; edge = edge->next) {
17547                                 change |= reg_in(state, blocks, rb, edge->member);
17548                         }
17549                         /* Add use to in... */
17550                         change |= use_in(state, rb);
17551                 }
17552         } while(change);
17553         return blocks;
17554 }
17555
17556 static void free_variable_lifetimes(struct compile_state *state, 
17557         struct basic_blocks *bb, struct reg_block *blocks)
17558 {
17559         int i;
17560         /* free in_set && out_set on each block */
17561         for(i = 1; i <= bb->last_vertex; i++) {
17562                 struct triple_reg_set *entry, *next;
17563                 struct reg_block *rb;
17564                 rb = &blocks[i];
17565                 for(entry = rb->in; entry ; entry = next) {
17566                         next = entry->next;
17567                         do_triple_unset(&rb->in, entry->member);
17568                 }
17569                 for(entry = rb->out; entry; entry = next) {
17570                         next = entry->next;
17571                         do_triple_unset(&rb->out, entry->member);
17572                 }
17573         }
17574         xfree(blocks);
17575
17576 }
17577
17578 typedef void (*wvl_cb_t)(
17579         struct compile_state *state, 
17580         struct reg_block *blocks, struct triple_reg_set *live, 
17581         struct reg_block *rb, struct triple *ins, void *arg);
17582
17583 static void walk_variable_lifetimes(struct compile_state *state,
17584         struct basic_blocks *bb, struct reg_block *blocks, 
17585         wvl_cb_t cb, void *arg)
17586 {
17587         int i;
17588         
17589         for(i = 1; i <= state->bb.last_vertex; i++) {
17590                 struct triple_reg_set *live;
17591                 struct triple_reg_set *entry, *next;
17592                 struct triple *ptr, *prev;
17593                 struct reg_block *rb;
17594                 struct block *block;
17595                 int done;
17596
17597                 /* Get the blocks */
17598                 rb = &blocks[i];
17599                 block = rb->block;
17600
17601                 /* Copy out into live */
17602                 live = 0;
17603                 for(entry = rb->out; entry; entry = next) {
17604                         next = entry->next;
17605                         do_triple_set(&live, entry->member, entry->new);
17606                 }
17607                 /* Walk through the basic block calculating live */
17608                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17609                         struct triple **expr;
17610
17611                         prev = ptr->prev;
17612                         done = (ptr == block->first);
17613
17614                         /* Ensure the current definition is in live */
17615                         if (triple_is_def(state, ptr)) {
17616                                 do_triple_set(&live, ptr, 0);
17617                         }
17618
17619                         /* Inform the callback function of what is
17620                          * going on.
17621                          */
17622                          cb(state, blocks, live, rb, ptr, arg);
17623                         
17624                         /* Remove the current definition from live */
17625                         do_triple_unset(&live, ptr);
17626
17627                         /* Add the current uses to live.
17628                          *
17629                          * It is safe to skip phi functions because they do
17630                          * not have any block local uses, and the block
17631                          * output sets already properly account for what
17632                          * control flow depedent uses phi functions do have.
17633                          */
17634                         if (ptr->op == OP_PHI) {
17635                                 continue;
17636                         }
17637                         expr = triple_rhs(state, ptr, 0);
17638                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17639                                 /* If the triple is not a definition skip it. */
17640                                 if (!*expr || !triple_is_def(state, *expr)) {
17641                                         continue;
17642                                 }
17643                                 do_triple_set(&live, *expr, 0);
17644                         }
17645                 }
17646                 /* Free live */
17647                 for(entry = live; entry; entry = next) {
17648                         next = entry->next;
17649                         do_triple_unset(&live, entry->member);
17650                 }
17651         }
17652 }
17653
17654 struct print_live_variable_info {
17655         struct reg_block *rb;
17656         FILE *fp;
17657 };
17658 static void print_live_variables_block(
17659         struct compile_state *state, struct block *block, void *arg)
17660
17661 {
17662         struct print_live_variable_info *info = arg;
17663         struct block_set *edge;
17664         FILE *fp = info->fp;
17665         struct reg_block *rb;
17666         struct triple *ptr;
17667         int phi_present;
17668         int done;
17669         rb = &info->rb[block->vertex];
17670
17671         fprintf(fp, "\nblock: %p (%d),",
17672                 block,  block->vertex);
17673         for(edge = block->edges; edge; edge = edge->next) {
17674                 fprintf(fp, " %p<-%p",
17675                         edge->member, 
17676                         edge->member && edge->member->use?edge->member->use->member : 0);
17677         }
17678         fprintf(fp, "\n");
17679         if (rb->in) {
17680                 struct triple_reg_set *in_set;
17681                 fprintf(fp, "        in:");
17682                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17683                         fprintf(fp, " %-10p", in_set->member);
17684                 }
17685                 fprintf(fp, "\n");
17686         }
17687         phi_present = 0;
17688         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17689                 done = (ptr == block->last);
17690                 if (ptr->op == OP_PHI) {
17691                         phi_present = 1;
17692                         break;
17693                 }
17694         }
17695         if (phi_present) {
17696                 int edge;
17697                 for(edge = 0; edge < block->users; edge++) {
17698                         fprintf(fp, "     in(%d):", edge);
17699                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17700                                 struct triple **slot;
17701                                 done = (ptr == block->last);
17702                                 if (ptr->op != OP_PHI) {
17703                                         continue;
17704                                 }
17705                                 slot = &RHS(ptr, 0);
17706                                 fprintf(fp, " %-10p", slot[edge]);
17707                         }
17708                         fprintf(fp, "\n");
17709                 }
17710         }
17711         if (block->first->op == OP_LABEL) {
17712                 fprintf(fp, "%p:\n", block->first);
17713         }
17714         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17715                 done = (ptr == block->last);
17716                 display_triple(fp, ptr);
17717         }
17718         if (rb->out) {
17719                 struct triple_reg_set *out_set;
17720                 fprintf(fp, "       out:");
17721                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17722                         fprintf(fp, " %-10p", out_set->member);
17723                 }
17724                 fprintf(fp, "\n");
17725         }
17726         fprintf(fp, "\n");
17727 }
17728
17729 static void print_live_variables(struct compile_state *state, 
17730         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17731 {
17732         struct print_live_variable_info info;
17733         info.rb = rb;
17734         info.fp = fp;
17735         fprintf(fp, "\nlive variables by block\n");
17736         walk_blocks(state, bb, print_live_variables_block, &info);
17737
17738 }
17739
17740
17741 static int count_triples(struct compile_state *state)
17742 {
17743         struct triple *first, *ins;
17744         int triples = 0;
17745         first = state->first;
17746         ins = first;
17747         do {
17748                 triples++;
17749                 ins = ins->next;
17750         } while (ins != first);
17751         return triples;
17752 }
17753
17754
17755 struct dead_triple {
17756         struct triple *triple;
17757         struct dead_triple *work_next;
17758         struct block *block;
17759         int old_id;
17760         int flags;
17761 #define TRIPLE_FLAG_ALIVE 1
17762 #define TRIPLE_FLAG_FREE  1
17763 };
17764
17765 static void print_dead_triples(struct compile_state *state, 
17766         struct dead_triple *dtriple)
17767 {
17768         struct triple *first, *ins;
17769         struct dead_triple *dt;
17770         FILE *fp;
17771         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17772                 return;
17773         }
17774         fp = state->dbgout;
17775         fprintf(fp, "--------------- dtriples ---------------\n");
17776         first = state->first;
17777         ins = first;
17778         do {
17779                 dt = &dtriple[ins->id];
17780                 if ((ins->op == OP_LABEL) && (ins->use)) {
17781                         fprintf(fp, "\n%p:\n", ins);
17782                 }
17783                 fprintf(fp, "%c", 
17784                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17785                 display_triple(fp, ins);
17786                 if (triple_is_branch(state, ins)) {
17787                         fprintf(fp, "\n");
17788                 }
17789                 ins = ins->next;
17790         } while(ins != first);
17791         fprintf(fp, "\n");
17792 }
17793
17794
17795 static void awaken(
17796         struct compile_state *state,
17797         struct dead_triple *dtriple, struct triple **expr,
17798         struct dead_triple ***work_list_tail)
17799 {
17800         struct triple *triple;
17801         struct dead_triple *dt;
17802         if (!expr) {
17803                 return;
17804         }
17805         triple = *expr;
17806         if (!triple) {
17807                 return;
17808         }
17809         if (triple->id <= 0)  {
17810                 internal_error(state, triple, "bad triple id: %d",
17811                         triple->id);
17812         }
17813         if (triple->op == OP_NOOP) {
17814                 internal_error(state, triple, "awakening noop?");
17815                 return;
17816         }
17817         dt = &dtriple[triple->id];
17818         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17819                 dt->flags |= TRIPLE_FLAG_ALIVE;
17820                 if (!dt->work_next) {
17821                         **work_list_tail = dt;
17822                         *work_list_tail = &dt->work_next;
17823                 }
17824         }
17825 }
17826
17827 static void eliminate_inefectual_code(struct compile_state *state)
17828 {
17829         struct block *block;
17830         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17831         int triples, i;
17832         struct triple *first, *final, *ins;
17833
17834         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17835                 return;
17836         }
17837
17838         /* Setup the work list */
17839         work_list = 0;
17840         work_list_tail = &work_list;
17841
17842         first = state->first;
17843         final = state->first->prev;
17844
17845         /* Count how many triples I have */
17846         triples = count_triples(state);
17847
17848         /* Now put then in an array and mark all of the triples dead */
17849         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17850         
17851         ins = first;
17852         i = 1;
17853         block = 0;
17854         do {
17855                 dtriple[i].triple = ins;
17856                 dtriple[i].block  = block_of_triple(state, ins);
17857                 dtriple[i].flags  = 0;
17858                 dtriple[i].old_id = ins->id;
17859                 ins->id = i;
17860                 /* See if it is an operation we always keep */
17861                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17862                         awaken(state, dtriple, &ins, &work_list_tail);
17863                 }
17864                 i++;
17865                 ins = ins->next;
17866         } while(ins != first);
17867         while(work_list) {
17868                 struct block *block;
17869                 struct dead_triple *dt;
17870                 struct block_set *user;
17871                 struct triple **expr;
17872                 dt = work_list;
17873                 work_list = dt->work_next;
17874                 if (!work_list) {
17875                         work_list_tail = &work_list;
17876                 }
17877                 /* Make certain the block the current instruction is in lives */
17878                 block = block_of_triple(state, dt->triple);
17879                 awaken(state, dtriple, &block->first, &work_list_tail);
17880                 if (triple_is_branch(state, block->last)) {
17881                         awaken(state, dtriple, &block->last, &work_list_tail);
17882                 } else {
17883                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17884                 }
17885
17886                 /* Wake up the data depencencies of this triple */
17887                 expr = 0;
17888                 do {
17889                         expr = triple_rhs(state, dt->triple, expr);
17890                         awaken(state, dtriple, expr, &work_list_tail);
17891                 } while(expr);
17892                 do {
17893                         expr = triple_lhs(state, dt->triple, expr);
17894                         awaken(state, dtriple, expr, &work_list_tail);
17895                 } while(expr);
17896                 do {
17897                         expr = triple_misc(state, dt->triple, expr);
17898                         awaken(state, dtriple, expr, &work_list_tail);
17899                 } while(expr);
17900                 /* Wake up the forward control dependencies */
17901                 do {
17902                         expr = triple_targ(state, dt->triple, expr);
17903                         awaken(state, dtriple, expr, &work_list_tail);
17904                 } while(expr);
17905                 /* Wake up the reverse control dependencies of this triple */
17906                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17907                         struct triple *last;
17908                         last = user->member->last;
17909                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17910                                 internal_warning(state, last, "awakening noop?");
17911                                 last = last->prev;
17912                         }
17913                         awaken(state, dtriple, &last, &work_list_tail);
17914                 }
17915         }
17916         print_dead_triples(state, dtriple);
17917         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17918                 if ((dt->triple->op == OP_NOOP) && 
17919                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17920                         internal_error(state, dt->triple, "noop effective?");
17921                 }
17922                 dt->triple->id = dt->old_id;    /* Restore the color */
17923                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17924                         release_triple(state, dt->triple);
17925                 }
17926         }
17927         xfree(dtriple);
17928
17929         rebuild_ssa_form(state);
17930
17931         print_blocks(state, __func__, state->dbgout);
17932 }
17933
17934
17935 static void insert_mandatory_copies(struct compile_state *state)
17936 {
17937         struct triple *ins, *first;
17938
17939         /* The object is with a minimum of inserted copies,
17940          * to resolve in fundamental register conflicts between
17941          * register value producers and consumers.
17942          * Theoretically we may be greater than minimal when we
17943          * are inserting copies before instructions but that
17944          * case should be rare.
17945          */
17946         first = state->first;
17947         ins = first;
17948         do {
17949                 struct triple_set *entry, *next;
17950                 struct triple *tmp;
17951                 struct reg_info info;
17952                 unsigned reg, regcm;
17953                 int do_post_copy, do_pre_copy;
17954                 tmp = 0;
17955                 if (!triple_is_def(state, ins)) {
17956                         goto next;
17957                 }
17958                 /* Find the architecture specific color information */
17959                 info = find_lhs_pre_color(state, ins, 0);
17960                 if (info.reg >= MAX_REGISTERS) {
17961                         info.reg = REG_UNSET;
17962                 }
17963
17964                 reg = REG_UNSET;
17965                 regcm = arch_type_to_regcm(state, ins->type);
17966                 do_post_copy = do_pre_copy = 0;
17967
17968                 /* Walk through the uses of ins and check for conflicts */
17969                 for(entry = ins->use; entry; entry = next) {
17970                         struct reg_info rinfo;
17971                         int i;
17972                         next = entry->next;
17973                         i = find_rhs_use(state, entry->member, ins);
17974                         if (i < 0) {
17975                                 continue;
17976                         }
17977                         
17978                         /* Find the users color requirements */
17979                         rinfo = arch_reg_rhs(state, entry->member, i);
17980                         if (rinfo.reg >= MAX_REGISTERS) {
17981                                 rinfo.reg = REG_UNSET;
17982                         }
17983                         
17984                         /* See if I need a pre_copy */
17985                         if (rinfo.reg != REG_UNSET) {
17986                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
17987                                         do_pre_copy = 1;
17988                                 }
17989                                 reg = rinfo.reg;
17990                         }
17991                         regcm &= rinfo.regcm;
17992                         regcm = arch_regcm_normalize(state, regcm);
17993                         if (regcm == 0) {
17994                                 do_pre_copy = 1;
17995                         }
17996                         /* Always use pre_copies for constants.
17997                          * They do not take up any registers until a
17998                          * copy places them in one.
17999                          */
18000                         if ((info.reg == REG_UNNEEDED) && 
18001                                 (rinfo.reg != REG_UNNEEDED)) {
18002                                 do_pre_copy = 1;
18003                         }
18004                 }
18005                 do_post_copy =
18006                         !do_pre_copy &&
18007                         (((info.reg != REG_UNSET) && 
18008                                 (reg != REG_UNSET) &&
18009                                 (info.reg != reg)) ||
18010                         ((info.regcm & regcm) == 0));
18011
18012                 reg = info.reg;
18013                 regcm = info.regcm;
18014                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
18015                 for(entry = ins->use; entry; entry = next) {
18016                         struct reg_info rinfo;
18017                         int i;
18018                         next = entry->next;
18019                         i = find_rhs_use(state, entry->member, ins);
18020                         if (i < 0) {
18021                                 continue;
18022                         }
18023                         
18024                         /* Find the users color requirements */
18025                         rinfo = arch_reg_rhs(state, entry->member, i);
18026                         if (rinfo.reg >= MAX_REGISTERS) {
18027                                 rinfo.reg = REG_UNSET;
18028                         }
18029
18030                         /* Now see if it is time to do the pre_copy */
18031                         if (rinfo.reg != REG_UNSET) {
18032                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
18033                                         ((regcm & rinfo.regcm) == 0) ||
18034                                         /* Don't let a mandatory coalesce sneak
18035                                          * into a operation that is marked to prevent
18036                                          * coalescing.
18037                                          */
18038                                         ((reg != REG_UNNEEDED) &&
18039                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
18040                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
18041                                         ) {
18042                                         if (do_pre_copy) {
18043                                                 struct triple *user;
18044                                                 user = entry->member;
18045                                                 if (RHS(user, i) != ins) {
18046                                                         internal_error(state, user, "bad rhs");
18047                                                 }
18048                                                 tmp = pre_copy(state, user, i);
18049                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18050                                                 continue;
18051                                         } else {
18052                                                 do_post_copy = 1;
18053                                         }
18054                                 }
18055                                 reg = rinfo.reg;
18056                         }
18057                         if ((regcm & rinfo.regcm) == 0) {
18058                                 if (do_pre_copy) {
18059                                         struct triple *user;
18060                                         user = entry->member;
18061                                         if (RHS(user, i) != ins) {
18062                                                 internal_error(state, user, "bad rhs");
18063                                         }
18064                                         tmp = pre_copy(state, user, i);
18065                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18066                                         continue;
18067                                 } else {
18068                                         do_post_copy = 1;
18069                                 }
18070                         }
18071                         regcm &= rinfo.regcm;
18072                         
18073                 }
18074                 if (do_post_copy) {
18075                         struct reg_info pre, post;
18076                         tmp = post_copy(state, ins);
18077                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18078                         pre = arch_reg_lhs(state, ins, 0);
18079                         post = arch_reg_lhs(state, tmp, 0);
18080                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
18081                                 internal_error(state, tmp, "useless copy");
18082                         }
18083                 }
18084         next:
18085                 ins = ins->next;
18086         } while(ins != first);
18087
18088         print_blocks(state, __func__, state->dbgout);
18089 }
18090
18091
18092 struct live_range_edge;
18093 struct live_range_def;
18094 struct live_range {
18095         struct live_range_edge *edges;
18096         struct live_range_def *defs;
18097 /* Note. The list pointed to by defs is kept in order.
18098  * That is baring splits in the flow control
18099  * defs dominates defs->next wich dominates defs->next->next
18100  * etc.
18101  */
18102         unsigned color;
18103         unsigned classes;
18104         unsigned degree;
18105         unsigned length;
18106         struct live_range *group_next, **group_prev;
18107 };
18108
18109 struct live_range_edge {
18110         struct live_range_edge *next;
18111         struct live_range *node;
18112 };
18113
18114 struct live_range_def {
18115         struct live_range_def *next;
18116         struct live_range_def *prev;
18117         struct live_range *lr;
18118         struct triple *def;
18119         unsigned orig_id;
18120 };
18121
18122 #define LRE_HASH_SIZE 2048
18123 struct lre_hash {
18124         struct lre_hash *next;
18125         struct live_range *left;
18126         struct live_range *right;
18127 };
18128
18129
18130 struct reg_state {
18131         struct lre_hash *hash[LRE_HASH_SIZE];
18132         struct reg_block *blocks;
18133         struct live_range_def *lrd;
18134         struct live_range *lr;
18135         struct live_range *low, **low_tail;
18136         struct live_range *high, **high_tail;
18137         unsigned defs;
18138         unsigned ranges;
18139         int passes, max_passes;
18140 };
18141
18142
18143 struct print_interference_block_info {
18144         struct reg_state *rstate;
18145         FILE *fp;
18146         int need_edges;
18147 };
18148 static void print_interference_block(
18149         struct compile_state *state, struct block *block, void *arg)
18150
18151 {
18152         struct print_interference_block_info *info = arg;
18153         struct reg_state *rstate = info->rstate;
18154         struct block_set *edge;
18155         FILE *fp = info->fp;
18156         struct reg_block *rb;
18157         struct triple *ptr;
18158         int phi_present;
18159         int done;
18160         rb = &rstate->blocks[block->vertex];
18161
18162         fprintf(fp, "\nblock: %p (%d),",
18163                 block,  block->vertex);
18164         for(edge = block->edges; edge; edge = edge->next) {
18165                 fprintf(fp, " %p<-%p",
18166                         edge->member, 
18167                         edge->member && edge->member->use?edge->member->use->member : 0);
18168         }
18169         fprintf(fp, "\n");
18170         if (rb->in) {
18171                 struct triple_reg_set *in_set;
18172                 fprintf(fp, "        in:");
18173                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18174                         fprintf(fp, " %-10p", in_set->member);
18175                 }
18176                 fprintf(fp, "\n");
18177         }
18178         phi_present = 0;
18179         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18180                 done = (ptr == block->last);
18181                 if (ptr->op == OP_PHI) {
18182                         phi_present = 1;
18183                         break;
18184                 }
18185         }
18186         if (phi_present) {
18187                 int edge;
18188                 for(edge = 0; edge < block->users; edge++) {
18189                         fprintf(fp, "     in(%d):", edge);
18190                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18191                                 struct triple **slot;
18192                                 done = (ptr == block->last);
18193                                 if (ptr->op != OP_PHI) {
18194                                         continue;
18195                                 }
18196                                 slot = &RHS(ptr, 0);
18197                                 fprintf(fp, " %-10p", slot[edge]);
18198                         }
18199                         fprintf(fp, "\n");
18200                 }
18201         }
18202         if (block->first->op == OP_LABEL) {
18203                 fprintf(fp, "%p:\n", block->first);
18204         }
18205         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18206                 struct live_range *lr;
18207                 unsigned id;
18208                 int op;
18209                 op = ptr->op;
18210                 done = (ptr == block->last);
18211                 lr = rstate->lrd[ptr->id].lr;
18212                 
18213                 id = ptr->id;
18214                 ptr->id = rstate->lrd[id].orig_id;
18215                 SET_REG(ptr->id, lr->color);
18216                 display_triple(fp, ptr);
18217                 ptr->id = id;
18218
18219                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18220                         internal_error(state, ptr, "lr has no defs!");
18221                 }
18222                 if (info->need_edges) {
18223                         if (lr->defs) {
18224                                 struct live_range_def *lrd;
18225                                 fprintf(fp, "       range:");
18226                                 lrd = lr->defs;
18227                                 do {
18228                                         fprintf(fp, " %-10p", lrd->def);
18229                                         lrd = lrd->next;
18230                                 } while(lrd != lr->defs);
18231                                 fprintf(fp, "\n");
18232                         }
18233                         if (lr->edges > 0) {
18234                                 struct live_range_edge *edge;
18235                                 fprintf(fp, "       edges:");
18236                                 for(edge = lr->edges; edge; edge = edge->next) {
18237                                         struct live_range_def *lrd;
18238                                         lrd = edge->node->defs;
18239                                         do {
18240                                                 fprintf(fp, " %-10p", lrd->def);
18241                                                 lrd = lrd->next;
18242                                         } while(lrd != edge->node->defs);
18243                                         fprintf(fp, "|");
18244                                 }
18245                                 fprintf(fp, "\n");
18246                         }
18247                 }
18248                 /* Do a bunch of sanity checks */
18249                 valid_ins(state, ptr);
18250                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18251                         internal_error(state, ptr, "Invalid triple id: %d",
18252                                 ptr->id);
18253                 }
18254         }
18255         if (rb->out) {
18256                 struct triple_reg_set *out_set;
18257                 fprintf(fp, "       out:");
18258                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18259                         fprintf(fp, " %-10p", out_set->member);
18260                 }
18261                 fprintf(fp, "\n");
18262         }
18263         fprintf(fp, "\n");
18264 }
18265
18266 static void print_interference_blocks(
18267         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18268 {
18269         struct print_interference_block_info info;
18270         info.rstate = rstate;
18271         info.fp = fp;
18272         info.need_edges = need_edges;
18273         fprintf(fp, "\nlive variables by block\n");
18274         walk_blocks(state, &state->bb, print_interference_block, &info);
18275
18276 }
18277
18278 static unsigned regc_max_size(struct compile_state *state, int classes)
18279 {
18280         unsigned max_size;
18281         int i;
18282         max_size = 0;
18283         for(i = 0; i < MAX_REGC; i++) {
18284                 if (classes & (1 << i)) {
18285                         unsigned size;
18286                         size = arch_regc_size(state, i);
18287                         if (size > max_size) {
18288                                 max_size = size;
18289                         }
18290                 }
18291         }
18292         return max_size;
18293 }
18294
18295 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18296 {
18297         unsigned equivs[MAX_REG_EQUIVS];
18298         int i;
18299         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18300                 internal_error(state, 0, "invalid register");
18301         }
18302         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18303                 internal_error(state, 0, "invalid register");
18304         }
18305         arch_reg_equivs(state, equivs, reg1);
18306         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18307                 if (equivs[i] == reg2) {
18308                         return 1;
18309                 }
18310         }
18311         return 0;
18312 }
18313
18314 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18315 {
18316         unsigned equivs[MAX_REG_EQUIVS];
18317         int i;
18318         if (reg == REG_UNNEEDED) {
18319                 return;
18320         }
18321         arch_reg_equivs(state, equivs, reg);
18322         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18323                 used[equivs[i]] = 1;
18324         }
18325         return;
18326 }
18327
18328 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18329 {
18330         unsigned equivs[MAX_REG_EQUIVS];
18331         int i;
18332         if (reg == REG_UNNEEDED) {
18333                 return;
18334         }
18335         arch_reg_equivs(state, equivs, reg);
18336         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18337                 used[equivs[i]] += 1;
18338         }
18339         return;
18340 }
18341
18342 static unsigned int hash_live_edge(
18343         struct live_range *left, struct live_range *right)
18344 {
18345         unsigned int hash, val;
18346         unsigned long lval, rval;
18347         lval = ((unsigned long)left)/sizeof(struct live_range);
18348         rval = ((unsigned long)right)/sizeof(struct live_range);
18349         hash = 0;
18350         while(lval) {
18351                 val = lval & 0xff;
18352                 lval >>= 8;
18353                 hash = (hash *263) + val;
18354         }
18355         while(rval) {
18356                 val = rval & 0xff;
18357                 rval >>= 8;
18358                 hash = (hash *263) + val;
18359         }
18360         hash = hash & (LRE_HASH_SIZE - 1);
18361         return hash;
18362 }
18363
18364 static struct lre_hash **lre_probe(struct reg_state *rstate,
18365         struct live_range *left, struct live_range *right)
18366 {
18367         struct lre_hash **ptr;
18368         unsigned int index;
18369         /* Ensure left <= right */
18370         if (left > right) {
18371                 struct live_range *tmp;
18372                 tmp = left;
18373                 left = right;
18374                 right = tmp;
18375         }
18376         index = hash_live_edge(left, right);
18377         
18378         ptr = &rstate->hash[index];
18379         while(*ptr) {
18380                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18381                         break;
18382                 }
18383                 ptr = &(*ptr)->next;
18384         }
18385         return ptr;
18386 }
18387
18388 static int interfere(struct reg_state *rstate,
18389         struct live_range *left, struct live_range *right)
18390 {
18391         struct lre_hash **ptr;
18392         ptr = lre_probe(rstate, left, right);
18393         return ptr && *ptr;
18394 }
18395
18396 static void add_live_edge(struct reg_state *rstate, 
18397         struct live_range *left, struct live_range *right)
18398 {
18399         /* FIXME the memory allocation overhead is noticeable here... */
18400         struct lre_hash **ptr, *new_hash;
18401         struct live_range_edge *edge;
18402
18403         if (left == right) {
18404                 return;
18405         }
18406         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18407                 return;
18408         }
18409         /* Ensure left <= right */
18410         if (left > right) {
18411                 struct live_range *tmp;
18412                 tmp = left;
18413                 left = right;
18414                 right = tmp;
18415         }
18416         ptr = lre_probe(rstate, left, right);
18417         if (*ptr) {
18418                 return;
18419         }
18420 #if 0
18421         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18422                 left, right);
18423 #endif
18424         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18425         new_hash->next  = *ptr;
18426         new_hash->left  = left;
18427         new_hash->right = right;
18428         *ptr = new_hash;
18429
18430         edge = xmalloc(sizeof(*edge), "live_range_edge");
18431         edge->next   = left->edges;
18432         edge->node   = right;
18433         left->edges  = edge;
18434         left->degree += 1;
18435         
18436         edge = xmalloc(sizeof(*edge), "live_range_edge");
18437         edge->next    = right->edges;
18438         edge->node    = left;
18439         right->edges  = edge;
18440         right->degree += 1;
18441 }
18442
18443 static void remove_live_edge(struct reg_state *rstate,
18444         struct live_range *left, struct live_range *right)
18445 {
18446         struct live_range_edge *edge, **ptr;
18447         struct lre_hash **hptr, *entry;
18448         hptr = lre_probe(rstate, left, right);
18449         if (!hptr || !*hptr) {
18450                 return;
18451         }
18452         entry = *hptr;
18453         *hptr = entry->next;
18454         xfree(entry);
18455
18456         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18457                 edge = *ptr;
18458                 if (edge->node == right) {
18459                         *ptr = edge->next;
18460                         memset(edge, 0, sizeof(*edge));
18461                         xfree(edge);
18462                         right->degree--;
18463                         break;
18464                 }
18465         }
18466         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18467                 edge = *ptr;
18468                 if (edge->node == left) {
18469                         *ptr = edge->next;
18470                         memset(edge, 0, sizeof(*edge));
18471                         xfree(edge);
18472                         left->degree--;
18473                         break;
18474                 }
18475         }
18476 }
18477
18478 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18479 {
18480         struct live_range_edge *edge, *next;
18481         for(edge = range->edges; edge; edge = next) {
18482                 next = edge->next;
18483                 remove_live_edge(rstate, range, edge->node);
18484         }
18485 }
18486
18487 static void transfer_live_edges(struct reg_state *rstate, 
18488         struct live_range *dest, struct live_range *src)
18489 {
18490         struct live_range_edge *edge, *next;
18491         for(edge = src->edges; edge; edge = next) {
18492                 struct live_range *other;
18493                 next = edge->next;
18494                 other = edge->node;
18495                 remove_live_edge(rstate, src, other);
18496                 add_live_edge(rstate, dest, other);
18497         }
18498 }
18499
18500
18501 /* Interference graph...
18502  * 
18503  * new(n) --- Return a graph with n nodes but no edges.
18504  * add(g,x,y) --- Return a graph including g with an between x and y
18505  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18506  *                x and y in the graph g
18507  * degree(g, x) --- Return the degree of the node x in the graph g
18508  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18509  *
18510  * Implement with a hash table && a set of adjcency vectors.
18511  * The hash table supports constant time implementations of add and interfere.
18512  * The adjacency vectors support an efficient implementation of neighbors.
18513  */
18514
18515 /* 
18516  *     +---------------------------------------------------+
18517  *     |         +--------------+                          |
18518  *     v         v              |                          |
18519  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18520  *
18521  * -- In simplify implment optimistic coloring... (No backtracking)
18522  * -- Implement Rematerialization it is the only form of spilling we can perform
18523  *    Essentially this means dropping a constant from a register because
18524  *    we can regenerate it later.
18525  *
18526  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18527  *     coalesce at phi points...
18528  * --- Bias coloring if at all possible do the coalesing a compile time.
18529  *
18530  *
18531  */
18532
18533 static void different_colored(
18534         struct compile_state *state, struct reg_state *rstate, 
18535         struct triple *parent, struct triple *ins)
18536 {
18537         struct live_range *lr;
18538         struct triple **expr;
18539         lr = rstate->lrd[ins->id].lr;
18540         expr = triple_rhs(state, ins, 0);
18541         for(;expr; expr = triple_rhs(state, ins, expr)) {
18542                 struct live_range *lr2;
18543                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18544                         continue;
18545                 }
18546                 lr2 = rstate->lrd[(*expr)->id].lr;
18547                 if (lr->color == lr2->color) {
18548                         internal_error(state, ins, "live range too big");
18549                 }
18550         }
18551 }
18552
18553
18554 static struct live_range *coalesce_ranges(
18555         struct compile_state *state, struct reg_state *rstate,
18556         struct live_range *lr1, struct live_range *lr2)
18557 {
18558         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18559         unsigned color;
18560         unsigned classes;
18561         if (lr1 == lr2) {
18562                 return lr1;
18563         }
18564         if (!lr1->defs || !lr2->defs) {
18565                 internal_error(state, 0,
18566                         "cannot coalese dead live ranges");
18567         }
18568         if ((lr1->color == REG_UNNEEDED) ||
18569                 (lr2->color == REG_UNNEEDED)) {
18570                 internal_error(state, 0, 
18571                         "cannot coalesce live ranges without a possible color");
18572         }
18573         if ((lr1->color != lr2->color) &&
18574                 (lr1->color != REG_UNSET) &&
18575                 (lr2->color != REG_UNSET)) {
18576                 internal_error(state, lr1->defs->def, 
18577                         "cannot coalesce live ranges of different colors");
18578         }
18579         color = lr1->color;
18580         if (color == REG_UNSET) {
18581                 color = lr2->color;
18582         }
18583         classes = lr1->classes & lr2->classes;
18584         if (!classes) {
18585                 internal_error(state, lr1->defs->def,
18586                         "cannot coalesce live ranges with dissimilar register classes");
18587         }
18588         if (state->compiler->debug & DEBUG_COALESCING) {
18589                 FILE *fp = state->errout;
18590                 fprintf(fp, "coalescing:");
18591                 lrd = lr1->defs;
18592                 do {
18593                         fprintf(fp, " %p", lrd->def);
18594                         lrd = lrd->next;
18595                 } while(lrd != lr1->defs);
18596                 fprintf(fp, " |");
18597                 lrd = lr2->defs;
18598                 do {
18599                         fprintf(fp, " %p", lrd->def);
18600                         lrd = lrd->next;
18601                 } while(lrd != lr2->defs);
18602                 fprintf(fp, "\n");
18603         }
18604         /* If there is a clear dominate live range put it in lr1,
18605          * For purposes of this test phi functions are
18606          * considered dominated by the definitions that feed into
18607          * them. 
18608          */
18609         if ((lr1->defs->prev->def->op == OP_PHI) ||
18610                 ((lr2->defs->prev->def->op != OP_PHI) &&
18611                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18612                 struct live_range *tmp;
18613                 tmp = lr1;
18614                 lr1 = lr2;
18615                 lr2 = tmp;
18616         }
18617 #if 0
18618         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18619                 fprintf(state->errout, "lr1 post\n");
18620         }
18621         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18622                 fprintf(state->errout, "lr1 pre\n");
18623         }
18624         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18625                 fprintf(state->errout, "lr2 post\n");
18626         }
18627         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18628                 fprintf(state->errout, "lr2 pre\n");
18629         }
18630 #endif
18631 #if 0
18632         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18633                 lr1->defs->def,
18634                 lr1->color,
18635                 lr2->defs->def,
18636                 lr2->color);
18637 #endif
18638         
18639         /* Append lr2 onto lr1 */
18640 #warning "FIXME should this be a merge instead of a splice?"
18641         /* This FIXME item applies to the correctness of live_range_end 
18642          * and to the necessity of making multiple passes of coalesce_live_ranges.
18643          * A failure to find some coalesce opportunities in coaleace_live_ranges
18644          * does not impact the correct of the compiler just the efficiency with
18645          * which registers are allocated.
18646          */
18647         head = lr1->defs;
18648         mid1 = lr1->defs->prev;
18649         mid2 = lr2->defs;
18650         end  = lr2->defs->prev;
18651         
18652         head->prev = end;
18653         end->next  = head;
18654
18655         mid1->next = mid2;
18656         mid2->prev = mid1;
18657
18658         /* Fixup the live range in the added live range defs */
18659         lrd = head;
18660         do {
18661                 lrd->lr = lr1;
18662                 lrd = lrd->next;
18663         } while(lrd != head);
18664
18665         /* Mark lr2 as free. */
18666         lr2->defs = 0;
18667         lr2->color = REG_UNNEEDED;
18668         lr2->classes = 0;
18669
18670         if (!lr1->defs) {
18671                 internal_error(state, 0, "lr1->defs == 0 ?");
18672         }
18673
18674         lr1->color   = color;
18675         lr1->classes = classes;
18676
18677         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18678         transfer_live_edges(rstate, lr1, lr2);
18679
18680         return lr1;
18681 }
18682
18683 static struct live_range_def *live_range_head(
18684         struct compile_state *state, struct live_range *lr,
18685         struct live_range_def *last)
18686 {
18687         struct live_range_def *result;
18688         result = 0;
18689         if (last == 0) {
18690                 result = lr->defs;
18691         }
18692         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18693                 result = last->next;
18694         }
18695         return result;
18696 }
18697
18698 static struct live_range_def *live_range_end(
18699         struct compile_state *state, struct live_range *lr,
18700         struct live_range_def *last)
18701 {
18702         struct live_range_def *result;
18703         result = 0;
18704         if (last == 0) {
18705                 result = lr->defs->prev;
18706         }
18707         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18708                 result = last->prev;
18709         }
18710         return result;
18711 }
18712
18713
18714 static void initialize_live_ranges(
18715         struct compile_state *state, struct reg_state *rstate)
18716 {
18717         struct triple *ins, *first;
18718         size_t count, size;
18719         int i, j;
18720
18721         first = state->first;
18722         /* First count how many instructions I have.
18723          */
18724         count = count_triples(state);
18725         /* Potentially I need one live range definitions for each
18726          * instruction.
18727          */
18728         rstate->defs = count;
18729         /* Potentially I need one live range for each instruction
18730          * plus an extra for the dummy live range.
18731          */
18732         rstate->ranges = count + 1;
18733         size = sizeof(rstate->lrd[0]) * rstate->defs;
18734         rstate->lrd = xcmalloc(size, "live_range_def");
18735         size = sizeof(rstate->lr[0]) * rstate->ranges;
18736         rstate->lr  = xcmalloc(size, "live_range");
18737
18738         /* Setup the dummy live range */
18739         rstate->lr[0].classes = 0;
18740         rstate->lr[0].color = REG_UNSET;
18741         rstate->lr[0].defs = 0;
18742         i = j = 0;
18743         ins = first;
18744         do {
18745                 /* If the triple is a variable give it a live range */
18746                 if (triple_is_def(state, ins)) {
18747                         struct reg_info info;
18748                         /* Find the architecture specific color information */
18749                         info = find_def_color(state, ins);
18750                         i++;
18751                         rstate->lr[i].defs    = &rstate->lrd[j];
18752                         rstate->lr[i].color   = info.reg;
18753                         rstate->lr[i].classes = info.regcm;
18754                         rstate->lr[i].degree  = 0;
18755                         rstate->lrd[j].lr = &rstate->lr[i];
18756                 } 
18757                 /* Otherwise give the triple the dummy live range. */
18758                 else {
18759                         rstate->lrd[j].lr = &rstate->lr[0];
18760                 }
18761
18762                 /* Initalize the live_range_def */
18763                 rstate->lrd[j].next    = &rstate->lrd[j];
18764                 rstate->lrd[j].prev    = &rstate->lrd[j];
18765                 rstate->lrd[j].def     = ins;
18766                 rstate->lrd[j].orig_id = ins->id;
18767                 ins->id = j;
18768
18769                 j++;
18770                 ins = ins->next;
18771         } while(ins != first);
18772         rstate->ranges = i;
18773
18774         /* Make a second pass to handle achitecture specific register
18775          * constraints.
18776          */
18777         ins = first;
18778         do {
18779                 int zlhs, zrhs, i, j;
18780                 if (ins->id > rstate->defs) {
18781                         internal_error(state, ins, "bad id");
18782                 }
18783                 
18784                 /* Walk through the template of ins and coalesce live ranges */
18785                 zlhs = ins->lhs;
18786                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18787                         zlhs = 1;
18788                 }
18789                 zrhs = ins->rhs;
18790
18791                 if (state->compiler->debug & DEBUG_COALESCING2) {
18792                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18793                                 ins, zlhs, zrhs);
18794                 }
18795
18796                 for(i = 0; i < zlhs; i++) {
18797                         struct reg_info linfo;
18798                         struct live_range_def *lhs;
18799                         linfo = arch_reg_lhs(state, ins, i);
18800                         if (linfo.reg < MAX_REGISTERS) {
18801                                 continue;
18802                         }
18803                         if (triple_is_def(state, ins)) {
18804                                 lhs = &rstate->lrd[ins->id];
18805                         } else {
18806                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18807                         }
18808
18809                         if (state->compiler->debug & DEBUG_COALESCING2) {
18810                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18811                                         i, lhs, linfo.reg);
18812                         }
18813
18814                         for(j = 0; j < zrhs; j++) {
18815                                 struct reg_info rinfo;
18816                                 struct live_range_def *rhs;
18817                                 rinfo = arch_reg_rhs(state, ins, j);
18818                                 if (rinfo.reg < MAX_REGISTERS) {
18819                                         continue;
18820                                 }
18821                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18822
18823                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18824                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18825                                                 j, rhs, rinfo.reg);
18826                                 }
18827
18828                                 if (rinfo.reg == linfo.reg) {
18829                                         coalesce_ranges(state, rstate, 
18830                                                 lhs->lr, rhs->lr);
18831                                 }
18832                         }
18833                 }
18834                 ins = ins->next;
18835         } while(ins != first);
18836 }
18837
18838 static void graph_ins(
18839         struct compile_state *state, 
18840         struct reg_block *blocks, struct triple_reg_set *live, 
18841         struct reg_block *rb, struct triple *ins, void *arg)
18842 {
18843         struct reg_state *rstate = arg;
18844         struct live_range *def;
18845         struct triple_reg_set *entry;
18846
18847         /* If the triple is not a definition
18848          * we do not have a definition to add to
18849          * the interference graph.
18850          */
18851         if (!triple_is_def(state, ins)) {
18852                 return;
18853         }
18854         def = rstate->lrd[ins->id].lr;
18855         
18856         /* Create an edge between ins and everything that is
18857          * alive, unless the live_range cannot share
18858          * a physical register with ins.
18859          */
18860         for(entry = live; entry; entry = entry->next) {
18861                 struct live_range *lr;
18862                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18863                         internal_error(state, 0, "bad entry?");
18864                 }
18865                 lr = rstate->lrd[entry->member->id].lr;
18866                 if (def == lr) {
18867                         continue;
18868                 }
18869                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18870                         continue;
18871                 }
18872                 add_live_edge(rstate, def, lr);
18873         }
18874         return;
18875 }
18876
18877 static struct live_range *get_verify_live_range(
18878         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18879 {
18880         struct live_range *lr;
18881         struct live_range_def *lrd;
18882         int ins_found;
18883         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18884                 internal_error(state, ins, "bad ins?");
18885         }
18886         lr = rstate->lrd[ins->id].lr;
18887         ins_found = 0;
18888         lrd = lr->defs;
18889         do {
18890                 if (lrd->def == ins) {
18891                         ins_found = 1;
18892                 }
18893                 lrd = lrd->next;
18894         } while(lrd != lr->defs);
18895         if (!ins_found) {
18896                 internal_error(state, ins, "ins not in live range");
18897         }
18898         return lr;
18899 }
18900
18901 static void verify_graph_ins(
18902         struct compile_state *state, 
18903         struct reg_block *blocks, struct triple_reg_set *live, 
18904         struct reg_block *rb, struct triple *ins, void *arg)
18905 {
18906         struct reg_state *rstate = arg;
18907         struct triple_reg_set *entry1, *entry2;
18908
18909
18910         /* Compare live against edges and make certain the code is working */
18911         for(entry1 = live; entry1; entry1 = entry1->next) {
18912                 struct live_range *lr1;
18913                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18914                 for(entry2 = live; entry2; entry2 = entry2->next) {
18915                         struct live_range *lr2;
18916                         struct live_range_edge *edge2;
18917                         int lr1_found;
18918                         int lr2_degree;
18919                         if (entry2 == entry1) {
18920                                 continue;
18921                         }
18922                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18923                         if (lr1 == lr2) {
18924                                 internal_error(state, entry2->member, 
18925                                         "live range with 2 values simultaneously alive");
18926                         }
18927                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18928                                 continue;
18929                         }
18930                         if (!interfere(rstate, lr1, lr2)) {
18931                                 internal_error(state, entry2->member, 
18932                                         "edges don't interfere?");
18933                         }
18934                                 
18935                         lr1_found = 0;
18936                         lr2_degree = 0;
18937                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
18938                                 lr2_degree++;
18939                                 if (edge2->node == lr1) {
18940                                         lr1_found = 1;
18941                                 }
18942                         }
18943                         if (lr2_degree != lr2->degree) {
18944                                 internal_error(state, entry2->member,
18945                                         "computed degree: %d does not match reported degree: %d\n",
18946                                         lr2_degree, lr2->degree);
18947                         }
18948                         if (!lr1_found) {
18949                                 internal_error(state, entry2->member, "missing edge");
18950                         }
18951                 }
18952         }
18953         return;
18954 }
18955
18956
18957 static void print_interference_ins(
18958         struct compile_state *state, 
18959         struct reg_block *blocks, struct triple_reg_set *live, 
18960         struct reg_block *rb, struct triple *ins, void *arg)
18961 {
18962         struct reg_state *rstate = arg;
18963         struct live_range *lr;
18964         unsigned id;
18965         FILE *fp = state->dbgout;
18966
18967         lr = rstate->lrd[ins->id].lr;
18968         id = ins->id;
18969         ins->id = rstate->lrd[id].orig_id;
18970         SET_REG(ins->id, lr->color);
18971         display_triple(state->dbgout, ins);
18972         ins->id = id;
18973
18974         if (lr->defs) {
18975                 struct live_range_def *lrd;
18976                 fprintf(fp, "       range:");
18977                 lrd = lr->defs;
18978                 do {
18979                         fprintf(fp, " %-10p", lrd->def);
18980                         lrd = lrd->next;
18981                 } while(lrd != lr->defs);
18982                 fprintf(fp, "\n");
18983         }
18984         if (live) {
18985                 struct triple_reg_set *entry;
18986                 fprintf(fp, "        live:");
18987                 for(entry = live; entry; entry = entry->next) {
18988                         fprintf(fp, " %-10p", entry->member);
18989                 }
18990                 fprintf(fp, "\n");
18991         }
18992         if (lr->edges) {
18993                 struct live_range_edge *entry;
18994                 fprintf(fp, "       edges:");
18995                 for(entry = lr->edges; entry; entry = entry->next) {
18996                         struct live_range_def *lrd;
18997                         lrd = entry->node->defs;
18998                         do {
18999                                 fprintf(fp, " %-10p", lrd->def);
19000                                 lrd = lrd->next;
19001                         } while(lrd != entry->node->defs);
19002                         fprintf(fp, "|");
19003                 }
19004                 fprintf(fp, "\n");
19005         }
19006         if (triple_is_branch(state, ins)) {
19007                 fprintf(fp, "\n");
19008         }
19009         return;
19010 }
19011
19012 static int coalesce_live_ranges(
19013         struct compile_state *state, struct reg_state *rstate)
19014 {
19015         /* At the point where a value is moved from one
19016          * register to another that value requires two
19017          * registers, thus increasing register pressure.
19018          * Live range coaleescing reduces the register
19019          * pressure by keeping a value in one register
19020          * longer.
19021          *
19022          * In the case of a phi function all paths leading
19023          * into it must be allocated to the same register
19024          * otherwise the phi function may not be removed.
19025          *
19026          * Forcing a value to stay in a single register
19027          * for an extended period of time does have
19028          * limitations when applied to non homogenous
19029          * register pool.  
19030          *
19031          * The two cases I have identified are:
19032          * 1) Two forced register assignments may
19033          *    collide.
19034          * 2) Registers may go unused because they
19035          *    are only good for storing the value
19036          *    and not manipulating it.
19037          *
19038          * Because of this I need to split live ranges,
19039          * even outside of the context of coalesced live
19040          * ranges.  The need to split live ranges does
19041          * impose some constraints on live range coalescing.
19042          *
19043          * - Live ranges may not be coalesced across phi
19044          *   functions.  This creates a 2 headed live
19045          *   range that cannot be sanely split.
19046          *
19047          * - phi functions (coalesced in initialize_live_ranges) 
19048          *   are handled as pre split live ranges so we will
19049          *   never attempt to split them.
19050          */
19051         int coalesced;
19052         int i;
19053
19054         coalesced = 0;
19055         for(i = 0; i <= rstate->ranges; i++) {
19056                 struct live_range *lr1;
19057                 struct live_range_def *lrd1;
19058                 lr1 = &rstate->lr[i];
19059                 if (!lr1->defs) {
19060                         continue;
19061                 }
19062                 lrd1 = live_range_end(state, lr1, 0);
19063                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
19064                         struct triple_set *set;
19065                         if (lrd1->def->op != OP_COPY) {
19066                                 continue;
19067                         }
19068                         /* Skip copies that are the result of a live range split. */
19069                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
19070                                 continue;
19071                         }
19072                         for(set = lrd1->def->use; set; set = set->next) {
19073                                 struct live_range_def *lrd2;
19074                                 struct live_range *lr2, *res;
19075
19076                                 lrd2 = &rstate->lrd[set->member->id];
19077
19078                                 /* Don't coalesce with instructions
19079                                  * that are the result of a live range
19080                                  * split.
19081                                  */
19082                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
19083                                         continue;
19084                                 }
19085                                 lr2 = rstate->lrd[set->member->id].lr;
19086                                 if (lr1 == lr2) {
19087                                         continue;
19088                                 }
19089                                 if ((lr1->color != lr2->color) &&
19090                                         (lr1->color != REG_UNSET) &&
19091                                         (lr2->color != REG_UNSET)) {
19092                                         continue;
19093                                 }
19094                                 if ((lr1->classes & lr2->classes) == 0) {
19095                                         continue;
19096                                 }
19097                                 
19098                                 if (interfere(rstate, lr1, lr2)) {
19099                                         continue;
19100                                 }
19101
19102                                 res = coalesce_ranges(state, rstate, lr1, lr2);
19103                                 coalesced += 1;
19104                                 if (res != lr1) {
19105                                         goto next;
19106                                 }
19107                         }
19108                 }
19109         next:
19110                 ;
19111         }
19112         return coalesced;
19113 }
19114
19115
19116 static void fix_coalesce_conflicts(struct compile_state *state,
19117         struct reg_block *blocks, struct triple_reg_set *live,
19118         struct reg_block *rb, struct triple *ins, void *arg)
19119 {
19120         int *conflicts = arg;
19121         int zlhs, zrhs, i, j;
19122
19123         /* See if we have a mandatory coalesce operation between
19124          * a lhs and a rhs value.  If so and the rhs value is also
19125          * alive then this triple needs to be pre copied.  Otherwise
19126          * we would have two definitions in the same live range simultaneously
19127          * alive.
19128          */
19129         zlhs = ins->lhs;
19130         if ((zlhs == 0) && triple_is_def(state, ins)) {
19131                 zlhs = 1;
19132         }
19133         zrhs = ins->rhs;
19134         for(i = 0; i < zlhs; i++) {
19135                 struct reg_info linfo;
19136                 linfo = arch_reg_lhs(state, ins, i);
19137                 if (linfo.reg < MAX_REGISTERS) {
19138                         continue;
19139                 }
19140                 for(j = 0; j < zrhs; j++) {
19141                         struct reg_info rinfo;
19142                         struct triple *rhs;
19143                         struct triple_reg_set *set;
19144                         int found;
19145                         found = 0;
19146                         rinfo = arch_reg_rhs(state, ins, j);
19147                         if (rinfo.reg != linfo.reg) {
19148                                 continue;
19149                         }
19150                         rhs = RHS(ins, j);
19151                         for(set = live; set && !found; set = set->next) {
19152                                 if (set->member == rhs) {
19153                                         found = 1;
19154                                 }
19155                         }
19156                         if (found) {
19157                                 struct triple *copy;
19158                                 copy = pre_copy(state, ins, j);
19159                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19160                                 (*conflicts)++;
19161                         }
19162                 }
19163         }
19164         return;
19165 }
19166
19167 static int correct_coalesce_conflicts(
19168         struct compile_state *state, struct reg_block *blocks)
19169 {
19170         int conflicts;
19171         conflicts = 0;
19172         walk_variable_lifetimes(state, &state->bb, blocks, 
19173                 fix_coalesce_conflicts, &conflicts);
19174         return conflicts;
19175 }
19176
19177 static void replace_set_use(struct compile_state *state,
19178         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19179 {
19180         struct triple_reg_set *set;
19181         for(set = head; set; set = set->next) {
19182                 if (set->member == orig) {
19183                         set->member = new;
19184                 }
19185         }
19186 }
19187
19188 static void replace_block_use(struct compile_state *state, 
19189         struct reg_block *blocks, struct triple *orig, struct triple *new)
19190 {
19191         int i;
19192 #warning "WISHLIST visit just those blocks that need it *"
19193         for(i = 1; i <= state->bb.last_vertex; i++) {
19194                 struct reg_block *rb;
19195                 rb = &blocks[i];
19196                 replace_set_use(state, rb->in, orig, new);
19197                 replace_set_use(state, rb->out, orig, new);
19198         }
19199 }
19200
19201 static void color_instructions(struct compile_state *state)
19202 {
19203         struct triple *ins, *first;
19204         first = state->first;
19205         ins = first;
19206         do {
19207                 if (triple_is_def(state, ins)) {
19208                         struct reg_info info;
19209                         info = find_lhs_color(state, ins, 0);
19210                         if (info.reg >= MAX_REGISTERS) {
19211                                 info.reg = REG_UNSET;
19212                         }
19213                         SET_INFO(ins->id, info);
19214                 }
19215                 ins = ins->next;
19216         } while(ins != first);
19217 }
19218
19219 static struct reg_info read_lhs_color(
19220         struct compile_state *state, struct triple *ins, int index)
19221 {
19222         struct reg_info info;
19223         if ((index == 0) && triple_is_def(state, ins)) {
19224                 info.reg   = ID_REG(ins->id);
19225                 info.regcm = ID_REGCM(ins->id);
19226         }
19227         else if (index < ins->lhs) {
19228                 info = read_lhs_color(state, LHS(ins, index), 0);
19229         }
19230         else {
19231                 internal_error(state, ins, "Bad lhs %d", index);
19232                 info.reg = REG_UNSET;
19233                 info.regcm = 0;
19234         }
19235         return info;
19236 }
19237
19238 static struct triple *resolve_tangle(
19239         struct compile_state *state, struct triple *tangle)
19240 {
19241         struct reg_info info, uinfo;
19242         struct triple_set *set, *next;
19243         struct triple *copy;
19244
19245 #warning "WISHLIST recalculate all affected instructions colors"
19246         info = find_lhs_color(state, tangle, 0);
19247         for(set = tangle->use; set; set = next) {
19248                 struct triple *user;
19249                 int i, zrhs;
19250                 next = set->next;
19251                 user = set->member;
19252                 zrhs = user->rhs;
19253                 for(i = 0; i < zrhs; i++) {
19254                         if (RHS(user, i) != tangle) {
19255                                 continue;
19256                         }
19257                         uinfo = find_rhs_post_color(state, user, i);
19258                         if (uinfo.reg == info.reg) {
19259                                 copy = pre_copy(state, user, i);
19260                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19261                                 SET_INFO(copy->id, uinfo);
19262                         }
19263                 }
19264         }
19265         copy = 0;
19266         uinfo = find_lhs_pre_color(state, tangle, 0);
19267         if (uinfo.reg == info.reg) {
19268                 struct reg_info linfo;
19269                 copy = post_copy(state, tangle);
19270                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19271                 linfo = find_lhs_color(state, copy, 0);
19272                 SET_INFO(copy->id, linfo);
19273         }
19274         info = find_lhs_color(state, tangle, 0);
19275         SET_INFO(tangle->id, info);
19276         
19277         return copy;
19278 }
19279
19280
19281 static void fix_tangles(struct compile_state *state,
19282         struct reg_block *blocks, struct triple_reg_set *live,
19283         struct reg_block *rb, struct triple *ins, void *arg)
19284 {
19285         int *tangles = arg;
19286         struct triple *tangle;
19287         do {
19288                 char used[MAX_REGISTERS];
19289                 struct triple_reg_set *set;
19290                 tangle = 0;
19291
19292                 /* Find out which registers have multiple uses at this point */
19293                 memset(used, 0, sizeof(used));
19294                 for(set = live; set; set = set->next) {
19295                         struct reg_info info;
19296                         info = read_lhs_color(state, set->member, 0);
19297                         if (info.reg == REG_UNSET) {
19298                                 continue;
19299                         }
19300                         reg_inc_used(state, used, info.reg);
19301                 }
19302                 
19303                 /* Now find the least dominated definition of a register in
19304                  * conflict I have seen so far.
19305                  */
19306                 for(set = live; set; set = set->next) {
19307                         struct reg_info info;
19308                         info = read_lhs_color(state, set->member, 0);
19309                         if (used[info.reg] < 2) {
19310                                 continue;
19311                         }
19312                         /* Changing copies that feed into phi functions
19313                          * is incorrect.
19314                          */
19315                         if (set->member->use && 
19316                                 (set->member->use->member->op == OP_PHI)) {
19317                                 continue;
19318                         }
19319                         if (!tangle || tdominates(state, set->member, tangle)) {
19320                                 tangle = set->member;
19321                         }
19322                 }
19323                 /* If I have found a tangle resolve it */
19324                 if (tangle) {
19325                         struct triple *post_copy;
19326                         (*tangles)++;
19327                         post_copy = resolve_tangle(state, tangle);
19328                         if (post_copy) {
19329                                 replace_block_use(state, blocks, tangle, post_copy);
19330                         }
19331                         if (post_copy && (tangle != ins)) {
19332                                 replace_set_use(state, live, tangle, post_copy);
19333                         }
19334                 }
19335         } while(tangle);
19336         return;
19337 }
19338
19339 static int correct_tangles(
19340         struct compile_state *state, struct reg_block *blocks)
19341 {
19342         int tangles;
19343         tangles = 0;
19344         color_instructions(state);
19345         walk_variable_lifetimes(state, &state->bb, blocks, 
19346                 fix_tangles, &tangles);
19347         return tangles;
19348 }
19349
19350
19351 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19352 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19353
19354 struct triple *find_constrained_def(
19355         struct compile_state *state, struct live_range *range, struct triple *constrained)
19356 {
19357         struct live_range_def *lrd, *lrd_next;
19358         lrd_next = range->defs;
19359         do {
19360                 struct reg_info info;
19361                 unsigned regcm;
19362
19363                 lrd = lrd_next;
19364                 lrd_next = lrd->next;
19365
19366                 regcm = arch_type_to_regcm(state, lrd->def->type);
19367                 info = find_lhs_color(state, lrd->def, 0);
19368                 regcm      = arch_regcm_reg_normalize(state, regcm);
19369                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19370                 /* If the 2 register class masks are equal then
19371                  * the current register class is not constrained.
19372                  */
19373                 if (regcm == info.regcm) {
19374                         continue;
19375                 }
19376                 
19377                 /* If there is just one use.
19378                  * That use cannot accept a larger register class.
19379                  * There are no intervening definitions except
19380                  * definitions that feed into that use.
19381                  * Then a triple is not constrained.
19382                  * FIXME handle this case!
19383                  */
19384 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19385                 
19386
19387                 /* Of the constrained live ranges deal with the
19388                  * least dominated one first.
19389                  */
19390                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19391                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19392                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19393                 }
19394                 if (!constrained || 
19395                         tdominates(state, lrd->def, constrained))
19396                 {
19397                         constrained = lrd->def;
19398                 }
19399         } while(lrd_next != range->defs);
19400         return constrained;
19401 }
19402
19403 static int split_constrained_ranges(
19404         struct compile_state *state, struct reg_state *rstate, 
19405         struct live_range *range)
19406 {
19407         /* Walk through the edges in conflict and our current live
19408          * range, and find definitions that are more severly constrained
19409          * than they type of data they contain require.
19410          * 
19411          * Then pick one of those ranges and relax the constraints.
19412          */
19413         struct live_range_edge *edge;
19414         struct triple *constrained;
19415
19416         constrained = 0;
19417         for(edge = range->edges; edge; edge = edge->next) {
19418                 constrained = find_constrained_def(state, edge->node, constrained);
19419         }
19420 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19421         if (!constrained) {
19422                 constrained = find_constrained_def(state, range, constrained);
19423         }
19424
19425         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19426                 fprintf(state->errout, "constrained: ");
19427                 display_triple(state->errout, constrained);
19428         }
19429         if (constrained) {
19430                 ids_from_rstate(state, rstate);
19431                 cleanup_rstate(state, rstate);
19432                 resolve_tangle(state, constrained);
19433         }
19434         return !!constrained;
19435 }
19436         
19437 static int split_ranges(
19438         struct compile_state *state, struct reg_state *rstate,
19439         char *used, struct live_range *range)
19440 {
19441         int split;
19442         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19443                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19444                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19445         }
19446         if ((range->color == REG_UNNEEDED) ||
19447                 (rstate->passes >= rstate->max_passes)) {
19448                 return 0;
19449         }
19450         split = split_constrained_ranges(state, rstate, range);
19451
19452         /* Ideally I would split the live range that will not be used
19453          * for the longest period of time in hopes that this will 
19454          * (a) allow me to spill a register or
19455          * (b) allow me to place a value in another register.
19456          *
19457          * So far I don't have a test case for this, the resolving
19458          * of mandatory constraints has solved all of my
19459          * know issues.  So I have choosen not to write any
19460          * code until I cat get a better feel for cases where
19461          * it would be useful to have.
19462          *
19463          */
19464 #warning "WISHLIST implement live range splitting..."
19465         
19466         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19467                 FILE *fp = state->errout;
19468                 print_interference_blocks(state, rstate, fp, 0);
19469                 print_dominators(state, fp, &state->bb);
19470         }
19471         return split;
19472 }
19473
19474 static FILE *cgdebug_fp(struct compile_state *state)
19475 {
19476         FILE *fp;
19477         fp = 0;
19478         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19479                 fp = state->errout;
19480         }
19481         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19482                 fp = state->dbgout;
19483         }
19484         return fp;
19485 }
19486
19487 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19488 {
19489         FILE *fp;
19490         fp = cgdebug_fp(state);
19491         if (fp) {
19492                 va_list args;
19493                 va_start(args, fmt);
19494                 vfprintf(fp, fmt, args);
19495                 va_end(args);
19496         }
19497 }
19498
19499 static void cgdebug_flush(struct compile_state *state)
19500 {
19501         FILE *fp;
19502         fp = cgdebug_fp(state);
19503         if (fp) {
19504                 fflush(fp);
19505         }
19506 }
19507
19508 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19509 {
19510         FILE *fp;
19511         fp = cgdebug_fp(state);
19512         if (fp) {
19513                 loc(fp, state, ins);
19514         }
19515 }
19516
19517 static int select_free_color(struct compile_state *state, 
19518         struct reg_state *rstate, struct live_range *range)
19519 {
19520         struct triple_set *entry;
19521         struct live_range_def *lrd;
19522         struct live_range_def *phi;
19523         struct live_range_edge *edge;
19524         char used[MAX_REGISTERS];
19525         struct triple **expr;
19526
19527         /* Instead of doing just the trivial color select here I try
19528          * a few extra things because a good color selection will help reduce
19529          * copies.
19530          */
19531
19532         /* Find the registers currently in use */
19533         memset(used, 0, sizeof(used));
19534         for(edge = range->edges; edge; edge = edge->next) {
19535                 if (edge->node->color == REG_UNSET) {
19536                         continue;
19537                 }
19538                 reg_fill_used(state, used, edge->node->color);
19539         }
19540
19541         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19542                 int i;
19543                 i = 0;
19544                 for(edge = range->edges; edge; edge = edge->next) {
19545                         i++;
19546                 }
19547                 cgdebug_printf(state, "\n%s edges: %d", 
19548                         tops(range->defs->def->op), i);
19549                 cgdebug_loc(state, range->defs->def);
19550                 cgdebug_printf(state, "\n");
19551                 for(i = 0; i < MAX_REGISTERS; i++) {
19552                         if (used[i]) {
19553                                 cgdebug_printf(state, "used: %s\n",
19554                                         arch_reg_str(i));
19555                         }
19556                 }
19557         }       
19558
19559         /* If a color is already assigned see if it will work */
19560         if (range->color != REG_UNSET) {
19561                 struct live_range_def *lrd;
19562                 if (!used[range->color]) {
19563                         return 1;
19564                 }
19565                 for(edge = range->edges; edge; edge = edge->next) {
19566                         if (edge->node->color != range->color) {
19567                                 continue;
19568                         }
19569                         warning(state, edge->node->defs->def, "edge: ");
19570                         lrd = edge->node->defs;
19571                         do {
19572                                 warning(state, lrd->def, " %p %s",
19573                                         lrd->def, tops(lrd->def->op));
19574                                 lrd = lrd->next;
19575                         } while(lrd != edge->node->defs);
19576                 }
19577                 lrd = range->defs;
19578                 warning(state, range->defs->def, "def: ");
19579                 do {
19580                         warning(state, lrd->def, " %p %s",
19581                                 lrd->def, tops(lrd->def->op));
19582                         lrd = lrd->next;
19583                 } while(lrd != range->defs);
19584                 internal_error(state, range->defs->def,
19585                         "live range with already used color %s",
19586                         arch_reg_str(range->color));
19587         }
19588
19589         /* If I feed into an expression reuse it's color.
19590          * This should help remove copies in the case of 2 register instructions
19591          * and phi functions.
19592          */
19593         phi = 0;
19594         lrd = live_range_end(state, range, 0);
19595         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19596                 entry = lrd->def->use;
19597                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19598                         struct live_range_def *insd;
19599                         unsigned regcm;
19600                         insd = &rstate->lrd[entry->member->id];
19601                         if (insd->lr->defs == 0) {
19602                                 continue;
19603                         }
19604                         if (!phi && (insd->def->op == OP_PHI) &&
19605                                 !interfere(rstate, range, insd->lr)) {
19606                                 phi = insd;
19607                         }
19608                         if (insd->lr->color == REG_UNSET) {
19609                                 continue;
19610                         }
19611                         regcm = insd->lr->classes;
19612                         if (((regcm & range->classes) == 0) ||
19613                                 (used[insd->lr->color])) {
19614                                 continue;
19615                         }
19616                         if (interfere(rstate, range, insd->lr)) {
19617                                 continue;
19618                         }
19619                         range->color = insd->lr->color;
19620                 }
19621         }
19622         /* If I feed into a phi function reuse it's color or the color
19623          * of something else that feeds into the phi function.
19624          */
19625         if (phi) {
19626                 if (phi->lr->color != REG_UNSET) {
19627                         if (used[phi->lr->color]) {
19628                                 range->color = phi->lr->color;
19629                         }
19630                 }
19631                 else {
19632                         expr = triple_rhs(state, phi->def, 0);
19633                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19634                                 struct live_range *lr;
19635                                 unsigned regcm;
19636                                 if (!*expr) {
19637                                         continue;
19638                                 }
19639                                 lr = rstate->lrd[(*expr)->id].lr;
19640                                 if (lr->color == REG_UNSET) {
19641                                         continue;
19642                                 }
19643                                 regcm = lr->classes;
19644                                 if (((regcm & range->classes) == 0) ||
19645                                         (used[lr->color])) {
19646                                         continue;
19647                                 }
19648                                 if (interfere(rstate, range, lr)) {
19649                                         continue;
19650                                 }
19651                                 range->color = lr->color;
19652                         }
19653                 }
19654         }
19655         /* If I don't interfere with a rhs node reuse it's color */
19656         lrd = live_range_head(state, range, 0);
19657         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19658                 expr = triple_rhs(state, lrd->def, 0);
19659                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19660                         struct live_range *lr;
19661                         unsigned regcm;
19662                         if (!*expr) {
19663                                 continue;
19664                         }
19665                         lr = rstate->lrd[(*expr)->id].lr;
19666                         if (lr->color == REG_UNSET) {
19667                                 continue;
19668                         }
19669                         regcm = lr->classes;
19670                         if (((regcm & range->classes) == 0) ||
19671                                 (used[lr->color])) {
19672                                 continue;
19673                         }
19674                         if (interfere(rstate, range, lr)) {
19675                                 continue;
19676                         }
19677                         range->color = lr->color;
19678                         break;
19679                 }
19680         }
19681         /* If I have not opportunitically picked a useful color
19682          * pick the first color that is free.
19683          */
19684         if (range->color == REG_UNSET) {
19685                 range->color = 
19686                         arch_select_free_register(state, used, range->classes);
19687         }
19688         if (range->color == REG_UNSET) {
19689                 struct live_range_def *lrd;
19690                 int i;
19691                 if (split_ranges(state, rstate, used, range)) {
19692                         return 0;
19693                 }
19694                 for(edge = range->edges; edge; edge = edge->next) {
19695                         warning(state, edge->node->defs->def, "edge reg %s",
19696                                 arch_reg_str(edge->node->color));
19697                         lrd = edge->node->defs;
19698                         do {
19699                                 warning(state, lrd->def, " %s %p",
19700                                         tops(lrd->def->op), lrd->def);
19701                                 lrd = lrd->next;
19702                         } while(lrd != edge->node->defs);
19703                 }
19704                 warning(state, range->defs->def, "range: ");
19705                 lrd = range->defs;
19706                 do {
19707                         warning(state, lrd->def, " %s %p",
19708                                 tops(lrd->def->op), lrd->def);
19709                         lrd = lrd->next;
19710                 } while(lrd != range->defs);
19711                         
19712                 warning(state, range->defs->def, "classes: %x",
19713                         range->classes);
19714                 for(i = 0; i < MAX_REGISTERS; i++) {
19715                         if (used[i]) {
19716                                 warning(state, range->defs->def, "used: %s",
19717                                         arch_reg_str(i));
19718                         }
19719                 }
19720                 error(state, range->defs->def, "too few registers");
19721         }
19722         range->classes &= arch_reg_regcm(state, range->color);
19723         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19724                 internal_error(state, range->defs->def, "select_free_color did not?");
19725         }
19726         return 1;
19727 }
19728
19729 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19730 {
19731         int colored;
19732         struct live_range_edge *edge;
19733         struct live_range *range;
19734         if (rstate->low) {
19735                 cgdebug_printf(state, "Lo: ");
19736                 range = rstate->low;
19737                 if (*range->group_prev != range) {
19738                         internal_error(state, 0, "lo: *prev != range?");
19739                 }
19740                 *range->group_prev = range->group_next;
19741                 if (range->group_next) {
19742                         range->group_next->group_prev = range->group_prev;
19743                 }
19744                 if (&range->group_next == rstate->low_tail) {
19745                         rstate->low_tail = range->group_prev;
19746                 }
19747                 if (rstate->low == range) {
19748                         internal_error(state, 0, "low: next != prev?");
19749                 }
19750         }
19751         else if (rstate->high) {
19752                 cgdebug_printf(state, "Hi: ");
19753                 range = rstate->high;
19754                 if (*range->group_prev != range) {
19755                         internal_error(state, 0, "hi: *prev != range?");
19756                 }
19757                 *range->group_prev = range->group_next;
19758                 if (range->group_next) {
19759                         range->group_next->group_prev = range->group_prev;
19760                 }
19761                 if (&range->group_next == rstate->high_tail) {
19762                         rstate->high_tail = range->group_prev;
19763                 }
19764                 if (rstate->high == range) {
19765                         internal_error(state, 0, "high: next != prev?");
19766                 }
19767         }
19768         else {
19769                 return 1;
19770         }
19771         cgdebug_printf(state, " %d\n", range - rstate->lr);
19772         range->group_prev = 0;
19773         for(edge = range->edges; edge; edge = edge->next) {
19774                 struct live_range *node;
19775                 node = edge->node;
19776                 /* Move nodes from the high to the low list */
19777                 if (node->group_prev && (node->color == REG_UNSET) &&
19778                         (node->degree == regc_max_size(state, node->classes))) {
19779                         if (*node->group_prev != node) {
19780                                 internal_error(state, 0, "move: *prev != node?");
19781                         }
19782                         *node->group_prev = node->group_next;
19783                         if (node->group_next) {
19784                                 node->group_next->group_prev = node->group_prev;
19785                         }
19786                         if (&node->group_next == rstate->high_tail) {
19787                                 rstate->high_tail = node->group_prev;
19788                         }
19789                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19790                         node->group_prev  = rstate->low_tail;
19791                         node->group_next  = 0;
19792                         *rstate->low_tail = node;
19793                         rstate->low_tail  = &node->group_next;
19794                         if (*node->group_prev != node) {
19795                                 internal_error(state, 0, "move2: *prev != node?");
19796                         }
19797                 }
19798                 node->degree -= 1;
19799         }
19800         colored = color_graph(state, rstate);
19801         if (colored) {
19802                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19803                 cgdebug_loc(state, range->defs->def);
19804                 cgdebug_flush(state);
19805                 colored = select_free_color(state, rstate, range);
19806                 if (colored) {
19807                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19808                 }
19809         }
19810         return colored;
19811 }
19812
19813 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19814 {
19815         struct live_range *lr;
19816         struct live_range_edge *edge;
19817         struct triple *ins, *first;
19818         char used[MAX_REGISTERS];
19819         first = state->first;
19820         ins = first;
19821         do {
19822                 if (triple_is_def(state, ins)) {
19823                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19824                                 internal_error(state, ins, 
19825                                         "triple without a live range def");
19826                         }
19827                         lr = rstate->lrd[ins->id].lr;
19828                         if (lr->color == REG_UNSET) {
19829                                 internal_error(state, ins,
19830                                         "triple without a color");
19831                         }
19832                         /* Find the registers used by the edges */
19833                         memset(used, 0, sizeof(used));
19834                         for(edge = lr->edges; edge; edge = edge->next) {
19835                                 if (edge->node->color == REG_UNSET) {
19836                                         internal_error(state, 0,
19837                                                 "live range without a color");
19838                         }
19839                                 reg_fill_used(state, used, edge->node->color);
19840                         }
19841                         if (used[lr->color]) {
19842                                 internal_error(state, ins,
19843                                         "triple with already used color");
19844                         }
19845                 }
19846                 ins = ins->next;
19847         } while(ins != first);
19848 }
19849
19850 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19851 {
19852         struct live_range_def *lrd;
19853         struct live_range *lr;
19854         struct triple *first, *ins;
19855         first = state->first;
19856         ins = first;
19857         do {
19858                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19859                         internal_error(state, ins, 
19860                                 "triple without a live range");
19861                 }
19862                 lrd = &rstate->lrd[ins->id];
19863                 lr = lrd->lr;
19864                 ins->id = lrd->orig_id;
19865                 SET_REG(ins->id, lr->color);
19866                 ins = ins->next;
19867         } while (ins != first);
19868 }
19869
19870 static struct live_range *merge_sort_lr(
19871         struct live_range *first, struct live_range *last)
19872 {
19873         struct live_range *mid, *join, **join_tail, *pick;
19874         size_t size;
19875         size = (last - first) + 1;
19876         if (size >= 2) {
19877                 mid = first + size/2;
19878                 first = merge_sort_lr(first, mid -1);
19879                 mid   = merge_sort_lr(mid, last);
19880                 
19881                 join = 0;
19882                 join_tail = &join;
19883                 /* merge the two lists */
19884                 while(first && mid) {
19885                         if ((first->degree < mid->degree) ||
19886                                 ((first->degree == mid->degree) &&
19887                                         (first->length < mid->length))) {
19888                                 pick = first;
19889                                 first = first->group_next;
19890                                 if (first) {
19891                                         first->group_prev = 0;
19892                                 }
19893                         }
19894                         else {
19895                                 pick = mid;
19896                                 mid = mid->group_next;
19897                                 if (mid) {
19898                                         mid->group_prev = 0;
19899                                 }
19900                         }
19901                         pick->group_next = 0;
19902                         pick->group_prev = join_tail;
19903                         *join_tail = pick;
19904                         join_tail = &pick->group_next;
19905                 }
19906                 /* Splice the remaining list */
19907                 pick = (first)? first : mid;
19908                 *join_tail = pick;
19909                 if (pick) { 
19910                         pick->group_prev = join_tail;
19911                 }
19912         }
19913         else {
19914                 if (!first->defs) {
19915                         first = 0;
19916                 }
19917                 join = first;
19918         }
19919         return join;
19920 }
19921
19922 static void ids_from_rstate(struct compile_state *state, 
19923         struct reg_state *rstate)
19924 {
19925         struct triple *ins, *first;
19926         if (!rstate->defs) {
19927                 return;
19928         }
19929         /* Display the graph if desired */
19930         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19931                 FILE *fp = state->dbgout;
19932                 print_interference_blocks(state, rstate, fp, 0);
19933                 print_control_flow(state, fp, &state->bb);
19934                 fflush(fp);
19935         }
19936         first = state->first;
19937         ins = first;
19938         do {
19939                 if (ins->id) {
19940                         struct live_range_def *lrd;
19941                         lrd = &rstate->lrd[ins->id];
19942                         ins->id = lrd->orig_id;
19943                 }
19944                 ins = ins->next;
19945         } while(ins != first);
19946 }
19947
19948 static void cleanup_live_edges(struct reg_state *rstate)
19949 {
19950         int i;
19951         /* Free the edges on each node */
19952         for(i = 1; i <= rstate->ranges; i++) {
19953                 remove_live_edges(rstate, &rstate->lr[i]);
19954         }
19955 }
19956
19957 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
19958 {
19959         cleanup_live_edges(rstate);
19960         xfree(rstate->lrd);
19961         xfree(rstate->lr);
19962
19963         /* Free the variable lifetime information */
19964         if (rstate->blocks) {
19965                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
19966         }
19967         rstate->defs = 0;
19968         rstate->ranges = 0;
19969         rstate->lrd = 0;
19970         rstate->lr = 0;
19971         rstate->blocks = 0;
19972 }
19973
19974 static void verify_consistency(struct compile_state *state);
19975 static void allocate_registers(struct compile_state *state)
19976 {
19977         struct reg_state rstate;
19978         int colored;
19979
19980         /* Clear out the reg_state */
19981         memset(&rstate, 0, sizeof(rstate));
19982         rstate.max_passes = state->compiler->max_allocation_passes;
19983
19984         do {
19985                 struct live_range **point, **next;
19986                 int conflicts;
19987                 int tangles;
19988                 int coalesced;
19989
19990                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19991                         FILE *fp = state->errout;
19992                         fprintf(fp, "pass: %d\n", rstate.passes);
19993                         fflush(fp);
19994                 }
19995
19996                 /* Restore ids */
19997                 ids_from_rstate(state, &rstate);
19998
19999                 /* Cleanup the temporary data structures */
20000                 cleanup_rstate(state, &rstate);
20001
20002                 /* Compute the variable lifetimes */
20003                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
20004
20005                 /* Fix invalid mandatory live range coalesce conflicts */
20006                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
20007
20008                 /* Fix two simultaneous uses of the same register.
20009                  * In a few pathlogical cases a partial untangle moves
20010                  * the tangle to a part of the graph we won't revisit.
20011                  * So we keep looping until we have no more tangle fixes
20012                  * to apply.
20013                  */
20014                 do {
20015                         tangles = correct_tangles(state, rstate.blocks);
20016                 } while(tangles);
20017
20018                 
20019                 print_blocks(state, "resolve_tangles", state->dbgout);
20020                 verify_consistency(state);
20021                 
20022                 /* Allocate and initialize the live ranges */
20023                 initialize_live_ranges(state, &rstate);
20024
20025                 /* Note currently doing coalescing in a loop appears to 
20026                  * buys me nothing.  The code is left this way in case
20027                  * there is some value in it.  Or if a future bugfix
20028                  * yields some benefit.
20029                  */
20030                 do {
20031                         if (state->compiler->debug & DEBUG_COALESCING) {
20032                                 fprintf(state->errout, "coalescing\n");
20033                         }
20034
20035                         /* Remove any previous live edge calculations */
20036                         cleanup_live_edges(&rstate);
20037
20038                         /* Compute the interference graph */
20039                         walk_variable_lifetimes(
20040                                 state, &state->bb, rstate.blocks, 
20041                                 graph_ins, &rstate);
20042                         
20043                         /* Display the interference graph if desired */
20044                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
20045                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
20046                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
20047                                 walk_variable_lifetimes(
20048                                         state, &state->bb, rstate.blocks, 
20049                                         print_interference_ins, &rstate);
20050                         }
20051                         
20052                         coalesced = coalesce_live_ranges(state, &rstate);
20053
20054                         if (state->compiler->debug & DEBUG_COALESCING) {
20055                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
20056                         }
20057                 } while(coalesced);
20058
20059 #if DEBUG_CONSISTENCY > 1
20060 # if 0
20061                 fprintf(state->errout, "verify_graph_ins...\n");
20062 # endif
20063                 /* Verify the interference graph */
20064                 walk_variable_lifetimes(
20065                         state, &state->bb, rstate.blocks, 
20066                         verify_graph_ins, &rstate);
20067 # if 0
20068                 fprintf(state->errout, "verify_graph_ins done\n");
20069 #endif
20070 #endif
20071                         
20072                 /* Build the groups low and high.  But with the nodes
20073                  * first sorted by degree order.
20074                  */
20075                 rstate.low_tail  = &rstate.low;
20076                 rstate.high_tail = &rstate.high;
20077                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
20078                 if (rstate.high) {
20079                         rstate.high->group_prev = &rstate.high;
20080                 }
20081                 for(point = &rstate.high; *point; point = &(*point)->group_next)
20082                         ;
20083                 rstate.high_tail = point;
20084                 /* Walk through the high list and move everything that needs
20085                  * to be onto low.
20086                  */
20087                 for(point = &rstate.high; *point; point = next) {
20088                         struct live_range *range;
20089                         next = &(*point)->group_next;
20090                         range = *point;
20091                         
20092                         /* If it has a low degree or it already has a color
20093                          * place the node in low.
20094                          */
20095                         if ((range->degree < regc_max_size(state, range->classes)) ||
20096                                 (range->color != REG_UNSET)) {
20097                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
20098                                         range - rstate.lr, range->degree,
20099                                         (range->color != REG_UNSET) ? " (colored)": "");
20100                                 *range->group_prev = range->group_next;
20101                                 if (range->group_next) {
20102                                         range->group_next->group_prev = range->group_prev;
20103                                 }
20104                                 if (&range->group_next == rstate.high_tail) {
20105                                         rstate.high_tail = range->group_prev;
20106                                 }
20107                                 range->group_prev  = rstate.low_tail;
20108                                 range->group_next  = 0;
20109                                 *rstate.low_tail   = range;
20110                                 rstate.low_tail    = &range->group_next;
20111                                 next = point;
20112                         }
20113                         else {
20114                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
20115                                         range - rstate.lr, range->degree,
20116                                         (range->color != REG_UNSET) ? " (colored)": "");
20117                         }
20118                 }
20119                 /* Color the live_ranges */
20120                 colored = color_graph(state, &rstate);
20121                 rstate.passes++;
20122         } while (!colored);
20123
20124         /* Verify the graph was properly colored */
20125         verify_colors(state, &rstate);
20126
20127         /* Move the colors from the graph to the triples */
20128         color_triples(state, &rstate);
20129
20130         /* Cleanup the temporary data structures */
20131         cleanup_rstate(state, &rstate);
20132
20133         /* Display the new graph */
20134         print_blocks(state, __func__, state->dbgout);
20135 }
20136
20137 /* Sparce Conditional Constant Propogation
20138  * =========================================
20139  */
20140 struct ssa_edge;
20141 struct flow_block;
20142 struct lattice_node {
20143         unsigned old_id;
20144         struct triple *def;
20145         struct ssa_edge *out;
20146         struct flow_block *fblock;
20147         struct triple *val;
20148         /* lattice high   val == def
20149          * lattice const  is_const(val)
20150          * lattice low    other
20151          */
20152 };
20153 struct ssa_edge {
20154         struct lattice_node *src;
20155         struct lattice_node *dst;
20156         struct ssa_edge *work_next;
20157         struct ssa_edge *work_prev;
20158         struct ssa_edge *out_next;
20159 };
20160 struct flow_edge {
20161         struct flow_block *src;
20162         struct flow_block *dst;
20163         struct flow_edge *work_next;
20164         struct flow_edge *work_prev;
20165         struct flow_edge *in_next;
20166         struct flow_edge *out_next;
20167         int executable;
20168 };
20169 #define MAX_FLOW_BLOCK_EDGES 3
20170 struct flow_block {
20171         struct block *block;
20172         struct flow_edge *in;
20173         struct flow_edge *out;
20174         struct flow_edge *edges;
20175 };
20176
20177 struct scc_state {
20178         int ins_count;
20179         struct lattice_node *lattice;
20180         struct ssa_edge     *ssa_edges;
20181         struct flow_block   *flow_blocks;
20182         struct flow_edge    *flow_work_list;
20183         struct ssa_edge     *ssa_work_list;
20184 };
20185
20186
20187 static int is_scc_const(struct compile_state *state, struct triple *ins)
20188 {
20189         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20190 }
20191
20192 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20193 {
20194         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20195 }
20196
20197 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20198 {
20199         return is_scc_const(state, lnode->val);
20200 }
20201
20202 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20203 {
20204         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20205 }
20206
20207 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20208         struct flow_edge *fedge)
20209 {
20210         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20211                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20212                         fedge,
20213                         fedge->src->block?fedge->src->block->last->id: 0,
20214                         fedge->dst->block?fedge->dst->block->first->id: 0);
20215         }
20216         if ((fedge == scc->flow_work_list) ||
20217                 (fedge->work_next != fedge) ||
20218                 (fedge->work_prev != fedge)) {
20219
20220                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20221                         fprintf(state->errout, "dupped fedge: %p\n",
20222                                 fedge);
20223                 }
20224                 return;
20225         }
20226         if (!scc->flow_work_list) {
20227                 scc->flow_work_list = fedge;
20228                 fedge->work_next = fedge->work_prev = fedge;
20229         }
20230         else {
20231                 struct flow_edge *ftail;
20232                 ftail = scc->flow_work_list->work_prev;
20233                 fedge->work_next = ftail->work_next;
20234                 fedge->work_prev = ftail;
20235                 fedge->work_next->work_prev = fedge;
20236                 fedge->work_prev->work_next = fedge;
20237         }
20238 }
20239
20240 static struct flow_edge *scc_next_fedge(
20241         struct compile_state *state, struct scc_state *scc)
20242 {
20243         struct flow_edge *fedge;
20244         fedge = scc->flow_work_list;
20245         if (fedge) {
20246                 fedge->work_next->work_prev = fedge->work_prev;
20247                 fedge->work_prev->work_next = fedge->work_next;
20248                 if (fedge->work_next != fedge) {
20249                         scc->flow_work_list = fedge->work_next;
20250                 } else {
20251                         scc->flow_work_list = 0;
20252                 }
20253                 fedge->work_next = fedge->work_prev = fedge;
20254         }
20255         return fedge;
20256 }
20257
20258 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20259         struct ssa_edge *sedge)
20260 {
20261         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20262                 fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
20263                         sedge - scc->ssa_edges,
20264                         sedge->src->def->id,
20265                         sedge->dst->def->id);
20266         }
20267         if ((sedge == scc->ssa_work_list) ||
20268                 (sedge->work_next != sedge) ||
20269                 (sedge->work_prev != sedge)) {
20270
20271                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20272                         fprintf(state->errout, "dupped sedge: %5d\n",
20273                                 sedge - scc->ssa_edges);
20274                 }
20275                 return;
20276         }
20277         if (!scc->ssa_work_list) {
20278                 scc->ssa_work_list = sedge;
20279                 sedge->work_next = sedge->work_prev = sedge;
20280         }
20281         else {
20282                 struct ssa_edge *stail;
20283                 stail = scc->ssa_work_list->work_prev;
20284                 sedge->work_next = stail->work_next;
20285                 sedge->work_prev = stail;
20286                 sedge->work_next->work_prev = sedge;
20287                 sedge->work_prev->work_next = sedge;
20288         }
20289 }
20290
20291 static struct ssa_edge *scc_next_sedge(
20292         struct compile_state *state, struct scc_state *scc)
20293 {
20294         struct ssa_edge *sedge;
20295         sedge = scc->ssa_work_list;
20296         if (sedge) {
20297                 sedge->work_next->work_prev = sedge->work_prev;
20298                 sedge->work_prev->work_next = sedge->work_next;
20299                 if (sedge->work_next != sedge) {
20300                         scc->ssa_work_list = sedge->work_next;
20301                 } else {
20302                         scc->ssa_work_list = 0;
20303                 }
20304                 sedge->work_next = sedge->work_prev = sedge;
20305         }
20306         return sedge;
20307 }
20308
20309 static void initialize_scc_state(
20310         struct compile_state *state, struct scc_state *scc)
20311 {
20312         int ins_count, ssa_edge_count;
20313         int ins_index, ssa_edge_index, fblock_index;
20314         struct triple *first, *ins;
20315         struct block *block;
20316         struct flow_block *fblock;
20317
20318         memset(scc, 0, sizeof(*scc));
20319
20320         /* Inialize pass zero find out how much memory we need */
20321         first = state->first;
20322         ins = first;
20323         ins_count = ssa_edge_count = 0;
20324         do {
20325                 struct triple_set *edge;
20326                 ins_count += 1;
20327                 for(edge = ins->use; edge; edge = edge->next) {
20328                         ssa_edge_count++;
20329                 }
20330                 ins = ins->next;
20331         } while(ins != first);
20332         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20333                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20334                         ins_count, ssa_edge_count, state->bb.last_vertex);
20335         }
20336         scc->ins_count   = ins_count;
20337         scc->lattice     = 
20338                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20339         scc->ssa_edges   = 
20340                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20341         scc->flow_blocks = 
20342                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20343                         "flow_blocks");
20344
20345         /* Initialize pass one collect up the nodes */
20346         fblock = 0;
20347         block = 0;
20348         ins_index = ssa_edge_index = fblock_index = 0;
20349         ins = first;
20350         do {
20351                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20352                         block = ins->u.block;
20353                         if (!block) {
20354                                 internal_error(state, ins, "label without block");
20355                         }
20356                         fblock_index += 1;
20357                         block->vertex = fblock_index;
20358                         fblock = &scc->flow_blocks[fblock_index];
20359                         fblock->block = block;
20360                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20361                                 "flow_edges");
20362                 }
20363                 {
20364                         struct lattice_node *lnode;
20365                         ins_index += 1;
20366                         lnode = &scc->lattice[ins_index];
20367                         lnode->def = ins;
20368                         lnode->out = 0;
20369                         lnode->fblock = fblock;
20370                         lnode->val = ins; /* LATTICE HIGH */
20371                         if (lnode->val->op == OP_UNKNOWNVAL) {
20372                                 lnode->val = 0; /* LATTICE LOW by definition */
20373                         }
20374                         lnode->old_id = ins->id;
20375                         ins->id = ins_index;
20376                 }
20377                 ins = ins->next;
20378         } while(ins != first);
20379         /* Initialize pass two collect up the edges */
20380         block = 0;
20381         fblock = 0;
20382         ins = first;
20383         do {
20384                 {
20385                         struct triple_set *edge;
20386                         struct ssa_edge **stail;
20387                         struct lattice_node *lnode;
20388                         lnode = &scc->lattice[ins->id];
20389                         lnode->out = 0;
20390                         stail = &lnode->out;
20391                         for(edge = ins->use; edge; edge = edge->next) {
20392                                 struct ssa_edge *sedge;
20393                                 ssa_edge_index += 1;
20394                                 sedge = &scc->ssa_edges[ssa_edge_index];
20395                                 *stail = sedge;
20396                                 stail = &sedge->out_next;
20397                                 sedge->src = lnode;
20398                                 sedge->dst = &scc->lattice[edge->member->id];
20399                                 sedge->work_next = sedge->work_prev = sedge;
20400                                 sedge->out_next = 0;
20401                         }
20402                 }
20403                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20404                         struct flow_edge *fedge, **ftail;
20405                         struct block_set *bedge;
20406                         block = ins->u.block;
20407                         fblock = &scc->flow_blocks[block->vertex];
20408                         fblock->in = 0;
20409                         fblock->out = 0;
20410                         ftail = &fblock->out;
20411
20412                         fedge = fblock->edges;
20413                         bedge = block->edges;
20414                         for(; bedge; bedge = bedge->next, fedge++) {
20415                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20416                                 if (fedge->dst->block != bedge->member) {
20417                                         internal_error(state, 0, "block mismatch");
20418                                 }
20419                                 *ftail = fedge;
20420                                 ftail = &fedge->out_next;
20421                                 fedge->out_next = 0;
20422                         }
20423                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20424                                 fedge->src = fblock;
20425                                 fedge->work_next = fedge->work_prev = fedge;
20426                                 fedge->executable = 0;
20427                         }
20428                 }
20429                 ins = ins->next;
20430         } while (ins != first);
20431         block = 0;
20432         fblock = 0;
20433         ins = first;
20434         do {
20435                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20436                         struct flow_edge **ftail;
20437                         struct block_set *bedge;
20438                         block = ins->u.block;
20439                         fblock = &scc->flow_blocks[block->vertex];
20440                         ftail = &fblock->in;
20441                         for(bedge = block->use; bedge; bedge = bedge->next) {
20442                                 struct block *src_block;
20443                                 struct flow_block *sfblock;
20444                                 struct flow_edge *sfedge;
20445                                 src_block = bedge->member;
20446                                 sfblock = &scc->flow_blocks[src_block->vertex];
20447                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20448                                         if (sfedge->dst == fblock) {
20449                                                 break;
20450                                         }
20451                                 }
20452                                 if (!sfedge) {
20453                                         internal_error(state, 0, "edge mismatch");
20454                                 }
20455                                 *ftail = sfedge;
20456                                 ftail = &sfedge->in_next;
20457                                 sfedge->in_next = 0;
20458                         }
20459                 }
20460                 ins = ins->next;
20461         } while(ins != first);
20462         /* Setup a dummy block 0 as a node above the start node */
20463         {
20464                 struct flow_block *fblock, *dst;
20465                 struct flow_edge *fedge;
20466                 fblock = &scc->flow_blocks[0];
20467                 fblock->block = 0;
20468                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20469                 fblock->in = 0;
20470                 fblock->out = fblock->edges;
20471                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20472                 fedge = fblock->edges;
20473                 fedge->src        = fblock;
20474                 fedge->dst        = dst;
20475                 fedge->work_next  = fedge;
20476                 fedge->work_prev  = fedge;
20477                 fedge->in_next    = fedge->dst->in;
20478                 fedge->out_next   = 0;
20479                 fedge->executable = 0;
20480                 fedge->dst->in = fedge;
20481                 
20482                 /* Initialize the work lists */
20483                 scc->flow_work_list = 0;
20484                 scc->ssa_work_list  = 0;
20485                 scc_add_fedge(state, scc, fedge);
20486         }
20487         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20488                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20489                         ins_index, ssa_edge_index, fblock_index);
20490         }
20491 }
20492
20493         
20494 static void free_scc_state(
20495         struct compile_state *state, struct scc_state *scc)
20496 {
20497         int i;
20498         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20499                 struct flow_block *fblock;
20500                 fblock = &scc->flow_blocks[i];
20501                 if (fblock->edges) {
20502                         xfree(fblock->edges);
20503                         fblock->edges = 0;
20504                 }
20505         }
20506         xfree(scc->flow_blocks);
20507         xfree(scc->ssa_edges);
20508         xfree(scc->lattice);
20509         
20510 }
20511
20512 static struct lattice_node *triple_to_lattice(
20513         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20514 {
20515         if (ins->id <= 0) {
20516                 internal_error(state, ins, "bad id");
20517         }
20518         return &scc->lattice[ins->id];
20519 }
20520
20521 static struct triple *preserve_lval(
20522         struct compile_state *state, struct lattice_node *lnode)
20523 {
20524         struct triple *old;
20525         /* Preserve the original value */
20526         if (lnode->val) {
20527                 old = dup_triple(state, lnode->val);
20528                 if (lnode->val != lnode->def) {
20529                         xfree(lnode->val);
20530                 }
20531                 lnode->val = 0;
20532         } else {
20533                 old = 0;
20534         }
20535         return old;
20536 }
20537
20538 static int lval_changed(struct compile_state *state, 
20539         struct triple *old, struct lattice_node *lnode)
20540 {
20541         int changed;
20542         /* See if the lattice value has changed */
20543         changed = 1;
20544         if (!old && !lnode->val) {
20545                 changed = 0;
20546         }
20547         if (changed &&
20548                 lnode->val && old &&
20549                 (memcmp(lnode->val->param, old->param,
20550                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20551                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20552                 changed = 0;
20553         }
20554         if (old) {
20555                 xfree(old);
20556         }
20557         return changed;
20558
20559 }
20560
20561 static void scc_debug_lnode(
20562         struct compile_state *state, struct scc_state *scc,
20563         struct lattice_node *lnode, int changed)
20564 {
20565         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20566                 display_triple_changes(state->errout, lnode->val, lnode->def);
20567         }
20568         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20569                 FILE *fp = state->errout;
20570                 struct triple *val, **expr;
20571                 val = lnode->val? lnode->val : lnode->def;
20572                 fprintf(fp, "%p %s %3d %10s (",
20573                         lnode->def, 
20574                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20575                         lnode->def->id,
20576                         tops(lnode->def->op));
20577                 expr = triple_rhs(state, lnode->def, 0);
20578                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20579                         if (*expr) {
20580                                 fprintf(fp, " %d", (*expr)->id);
20581                         }
20582                 }
20583                 if (val->op == OP_INTCONST) {
20584                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20585                 }
20586                 fprintf(fp, " ) -> %s %s\n",
20587                         (is_lattice_hi(state, lnode)? "hi":
20588                                 is_lattice_const(state, lnode)? "const" : "lo"),
20589                         changed? "changed" : ""
20590                         );
20591         }
20592 }
20593
20594 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20595         struct lattice_node *lnode)
20596 {
20597         int changed;
20598         struct triple *old, *scratch;
20599         struct triple **dexpr, **vexpr;
20600         int count, i;
20601         
20602         /* Store the original value */
20603         old = preserve_lval(state, lnode);
20604
20605         /* Reinitialize the value */
20606         lnode->val = scratch = dup_triple(state, lnode->def);
20607         scratch->id = lnode->old_id;
20608         scratch->next     = scratch;
20609         scratch->prev     = scratch;
20610         scratch->use      = 0;
20611
20612         count = TRIPLE_SIZE(scratch);
20613         for(i = 0; i < count; i++) {
20614                 dexpr = &lnode->def->param[i];
20615                 vexpr = &scratch->param[i];
20616                 *vexpr = *dexpr;
20617                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20618                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20619                         *dexpr) {
20620                         struct lattice_node *tmp;
20621                         tmp = triple_to_lattice(state, scc, *dexpr);
20622                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20623                 }
20624         }
20625         if (triple_is_branch(state, scratch)) {
20626                 scratch->next = lnode->def->next;
20627         }
20628         /* Recompute the value */
20629 #warning "FIXME see if simplify does anything bad"
20630         /* So far it looks like only the strength reduction
20631          * optimization are things I need to worry about.
20632          */
20633         simplify(state, scratch);
20634         /* Cleanup my value */
20635         if (scratch->use) {
20636                 internal_error(state, lnode->def, "scratch used?");
20637         }
20638         if ((scratch->prev != scratch) ||
20639                 ((scratch->next != scratch) &&
20640                         (!triple_is_branch(state, lnode->def) ||
20641                                 (scratch->next != lnode->def->next)))) {
20642                 internal_error(state, lnode->def, "scratch in list?");
20643         }
20644         /* undo any uses... */
20645         count = TRIPLE_SIZE(scratch);
20646         for(i = 0; i < count; i++) {
20647                 vexpr = &scratch->param[i];
20648                 if (*vexpr) {
20649                         unuse_triple(*vexpr, scratch);
20650                 }
20651         }
20652         if (lnode->val->op == OP_UNKNOWNVAL) {
20653                 lnode->val = 0; /* Lattice low by definition */
20654         }
20655         /* Find the case when I am lattice high */
20656         if (lnode->val && 
20657                 (lnode->val->op == lnode->def->op) &&
20658                 (memcmp(lnode->val->param, lnode->def->param, 
20659                         count * sizeof(lnode->val->param[0])) == 0) &&
20660                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20661                 lnode->val = lnode->def;
20662         }
20663         /* Only allow lattice high when all of my inputs
20664          * are also lattice high.  Occassionally I can
20665          * have constants with a lattice low input, so
20666          * I do not need to check that case.
20667          */
20668         if (is_lattice_hi(state, lnode)) {
20669                 struct lattice_node *tmp;
20670                 int rhs;
20671                 rhs = lnode->val->rhs;
20672                 for(i = 0; i < rhs; i++) {
20673                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20674                         if (!is_lattice_hi(state, tmp)) {
20675                                 lnode->val = 0;
20676                                 break;
20677                         }
20678                 }
20679         }
20680         /* Find the cases that are always lattice lo */
20681         if (lnode->val && 
20682                 triple_is_def(state, lnode->val) &&
20683                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20684                 lnode->val = 0;
20685         }
20686         /* See if the lattice value has changed */
20687         changed = lval_changed(state, old, lnode);
20688         /* See if this value should not change */
20689         if ((lnode->val != lnode->def) && 
20690                 ((      !triple_is_def(state, lnode->def)  &&
20691                         !triple_is_cbranch(state, lnode->def)) ||
20692                         (lnode->def->op == OP_PIECE))) {
20693 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20694                 if (changed) {
20695                         internal_warning(state, lnode->def, "non def changes value?");
20696                 }
20697                 lnode->val = 0;
20698         }
20699
20700         /* See if we need to free the scratch value */
20701         if (lnode->val != scratch) {
20702                 xfree(scratch);
20703         }
20704         
20705         return changed;
20706 }
20707
20708
20709 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20710         struct lattice_node *lnode)
20711 {
20712         struct lattice_node *cond;
20713         struct flow_edge *left, *right;
20714         int changed;
20715
20716         /* Update the branch value */
20717         changed = compute_lnode_val(state, scc, lnode);
20718         scc_debug_lnode(state, scc, lnode, changed);
20719
20720         /* This only applies to conditional branches */
20721         if (!triple_is_cbranch(state, lnode->def)) {
20722                 internal_error(state, lnode->def, "not a conditional branch");
20723         }
20724
20725         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20726                 struct flow_edge *fedge;
20727                 FILE *fp = state->errout;
20728                 fprintf(fp, "%s: %d (",
20729                         tops(lnode->def->op),
20730                         lnode->def->id);
20731                 
20732                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20733                         fprintf(fp, " %d", fedge->dst->block->vertex);
20734                 }
20735                 fprintf(fp, " )");
20736                 if (lnode->def->rhs > 0) {
20737                         fprintf(fp, " <- %d",
20738                                 RHS(lnode->def, 0)->id);
20739                 }
20740                 fprintf(fp, "\n");
20741         }
20742         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20743         for(left = cond->fblock->out; left; left = left->out_next) {
20744                 if (left->dst->block->first == lnode->def->next) {
20745                         break;
20746                 }
20747         }
20748         if (!left) {
20749                 internal_error(state, lnode->def, "Cannot find left branch edge");
20750         }
20751         for(right = cond->fblock->out; right; right = right->out_next) {
20752                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20753                         break;
20754                 }
20755         }
20756         if (!right) {
20757                 internal_error(state, lnode->def, "Cannot find right branch edge");
20758         }
20759         /* I should only come here if the controlling expressions value
20760          * has changed, which means it must be either a constant or lo.
20761          */
20762         if (is_lattice_hi(state, cond)) {
20763                 internal_error(state, cond->def, "condition high?");
20764                 return;
20765         }
20766         if (is_lattice_lo(state, cond)) {
20767                 scc_add_fedge(state, scc, left);
20768                 scc_add_fedge(state, scc, right);
20769         }
20770         else if (cond->val->u.cval) {
20771                 scc_add_fedge(state, scc, right);
20772         } else {
20773                 scc_add_fedge(state, scc, left);
20774         }
20775
20776 }
20777
20778
20779 static void scc_add_sedge_dst(struct compile_state *state, 
20780         struct scc_state *scc, struct ssa_edge *sedge)
20781 {
20782         if (triple_is_cbranch(state, sedge->dst->def)) {
20783                 scc_visit_cbranch(state, scc, sedge->dst);
20784         }
20785         else if (triple_is_def(state, sedge->dst->def)) {
20786                 scc_add_sedge(state, scc, sedge);
20787         }
20788 }
20789
20790 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20791         struct lattice_node *lnode)
20792 {
20793         struct lattice_node *tmp;
20794         struct triple **slot, *old;
20795         struct flow_edge *fedge;
20796         int changed;
20797         int index;
20798         if (lnode->def->op != OP_PHI) {
20799                 internal_error(state, lnode->def, "not phi");
20800         }
20801         /* Store the original value */
20802         old = preserve_lval(state, lnode);
20803
20804         /* default to lattice high */
20805         lnode->val = lnode->def;
20806         slot = &RHS(lnode->def, 0);
20807         index = 0;
20808         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20809                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20810                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20811                                 index,
20812                                 fedge->dst->block->vertex,
20813                                 fedge->executable
20814                                 );
20815                 }
20816                 if (!fedge->executable) {
20817                         continue;
20818                 }
20819                 if (!slot[index]) {
20820                         internal_error(state, lnode->def, "no phi value");
20821                 }
20822                 tmp = triple_to_lattice(state, scc, slot[index]);
20823                 /* meet(X, lattice low) = lattice low */
20824                 if (is_lattice_lo(state, tmp)) {
20825                         lnode->val = 0;
20826                 }
20827                 /* meet(X, lattice high) = X */
20828                 else if (is_lattice_hi(state, tmp)) {
20829                         lnode->val = lnode->val;
20830                 }
20831                 /* meet(lattice high, X) = X */
20832                 else if (is_lattice_hi(state, lnode)) {
20833                         lnode->val = dup_triple(state, tmp->val);
20834                         /* Only change the type if necessary */
20835                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20836                                 lnode->val->type = lnode->def->type;
20837                         }
20838                 }
20839                 /* meet(const, const) = const or lattice low */
20840                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20841                         lnode->val = 0;
20842                 }
20843
20844                 /* meet(lattice low, X) = lattice low */
20845                 if (is_lattice_lo(state, lnode)) {
20846                         lnode->val = 0;
20847                         break;
20848                 }
20849         }
20850         changed = lval_changed(state, old, lnode);
20851         scc_debug_lnode(state, scc, lnode, changed);
20852
20853         /* If the lattice value has changed update the work lists. */
20854         if (changed) {
20855                 struct ssa_edge *sedge;
20856                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20857                         scc_add_sedge_dst(state, scc, sedge);
20858                 }
20859         }
20860 }
20861
20862
20863 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20864         struct lattice_node *lnode)
20865 {
20866         int changed;
20867
20868         if (!triple_is_def(state, lnode->def)) {
20869                 internal_warning(state, lnode->def, "not visiting an expression?");
20870         }
20871         changed = compute_lnode_val(state, scc, lnode);
20872         scc_debug_lnode(state, scc, lnode, changed);
20873
20874         if (changed) {
20875                 struct ssa_edge *sedge;
20876                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20877                         scc_add_sedge_dst(state, scc, sedge);
20878                 }
20879         }
20880 }
20881
20882 static void scc_writeback_values(
20883         struct compile_state *state, struct scc_state *scc)
20884 {
20885         struct triple *first, *ins;
20886         first = state->first;
20887         ins = first;
20888         do {
20889                 struct lattice_node *lnode;
20890                 lnode = triple_to_lattice(state, scc, ins);
20891                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20892                         if (is_lattice_hi(state, lnode) &&
20893                                 (lnode->val->op != OP_NOOP))
20894                         {
20895                                 struct flow_edge *fedge;
20896                                 int executable;
20897                                 executable = 0;
20898                                 for(fedge = lnode->fblock->in; 
20899                                     !executable && fedge; fedge = fedge->in_next) {
20900                                         executable |= fedge->executable;
20901                                 }
20902                                 if (executable) {
20903                                         internal_warning(state, lnode->def,
20904                                                 "lattice node %d %s->%s still high?",
20905                                                 ins->id, 
20906                                                 tops(lnode->def->op),
20907                                                 tops(lnode->val->op));
20908                                 }
20909                         }
20910                 }
20911
20912                 /* Restore id */
20913                 ins->id = lnode->old_id;
20914                 if (lnode->val && (lnode->val != ins)) {
20915                         /* See if it something I know how to write back */
20916                         switch(lnode->val->op) {
20917                         case OP_INTCONST:
20918                                 mkconst(state, ins, lnode->val->u.cval);
20919                                 break;
20920                         case OP_ADDRCONST:
20921                                 mkaddr_const(state, ins, 
20922                                         MISC(lnode->val, 0), lnode->val->u.cval);
20923                                 break;
20924                         default:
20925                                 /* By default don't copy the changes,
20926                                  * recompute them in place instead.
20927                                  */
20928                                 simplify(state, ins);
20929                                 break;
20930                         }
20931                         if (is_const(lnode->val) &&
20932                                 !constants_equal(state, lnode->val, ins)) {
20933                                 internal_error(state, 0, "constants not equal");
20934                         }
20935                         /* Free the lattice nodes */
20936                         xfree(lnode->val);
20937                         lnode->val = 0;
20938                 }
20939                 ins = ins->next;
20940         } while(ins != first);
20941 }
20942
20943 static void scc_transform(struct compile_state *state)
20944 {
20945         struct scc_state scc;
20946         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
20947                 return;
20948         }
20949
20950         initialize_scc_state(state, &scc);
20951
20952         while(scc.flow_work_list || scc.ssa_work_list) {
20953                 struct flow_edge *fedge;
20954                 struct ssa_edge *sedge;
20955                 struct flow_edge *fptr;
20956                 while((fedge = scc_next_fedge(state, &scc))) {
20957                         struct block *block;
20958                         struct triple *ptr;
20959                         struct flow_block *fblock;
20960                         int reps;
20961                         int done;
20962                         if (fedge->executable) {
20963                                 continue;
20964                         }
20965                         if (!fedge->dst) {
20966                                 internal_error(state, 0, "fedge without dst");
20967                         }
20968                         if (!fedge->src) {
20969                                 internal_error(state, 0, "fedge without src");
20970                         }
20971                         fedge->executable = 1;
20972                         fblock = fedge->dst;
20973                         block = fblock->block;
20974                         reps = 0;
20975                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20976                                 if (fptr->executable) {
20977                                         reps++;
20978                                 }
20979                         }
20980                         
20981                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20982                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
20983                                         block->vertex, reps);
20984                         }
20985
20986                         done = 0;
20987                         for(ptr = block->first; !done; ptr = ptr->next) {
20988                                 struct lattice_node *lnode;
20989                                 done = (ptr == block->last);
20990                                 lnode = &scc.lattice[ptr->id];
20991                                 if (ptr->op == OP_PHI) {
20992                                         scc_visit_phi(state, &scc, lnode);
20993                                 }
20994                                 else if ((reps == 1) && triple_is_def(state, ptr))
20995                                 {
20996                                         scc_visit_expr(state, &scc, lnode);
20997                                 }
20998                         }
20999                         /* Add unconditional branch edges */
21000                         if (!triple_is_cbranch(state, fblock->block->last)) {
21001                                 struct flow_edge *out;
21002                                 for(out = fblock->out; out; out = out->out_next) {
21003                                         scc_add_fedge(state, &scc, out);
21004                                 }
21005                         }
21006                 }
21007                 while((sedge = scc_next_sedge(state, &scc))) {
21008                         struct lattice_node *lnode;
21009                         struct flow_block *fblock;
21010                         lnode = sedge->dst;
21011                         fblock = lnode->fblock;
21012
21013                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
21014                                 fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
21015                                         sedge - scc.ssa_edges,
21016                                         sedge->src->def->id,
21017                                         sedge->dst->def->id);
21018                         }
21019
21020                         if (lnode->def->op == OP_PHI) {
21021                                 scc_visit_phi(state, &scc, lnode);
21022                         }
21023                         else {
21024                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
21025                                         if (fptr->executable) {
21026                                                 break;
21027                                         }
21028                                 }
21029                                 if (fptr) {
21030                                         scc_visit_expr(state, &scc, lnode);
21031                                 }
21032                         }
21033                 }
21034         }
21035         
21036         scc_writeback_values(state, &scc);
21037         free_scc_state(state, &scc);
21038         rebuild_ssa_form(state);
21039         
21040         print_blocks(state, __func__, state->dbgout);
21041 }
21042
21043
21044 static void transform_to_arch_instructions(struct compile_state *state)
21045 {
21046         struct triple *ins, *first;
21047         first = state->first;
21048         ins = first;
21049         do {
21050                 ins = transform_to_arch_instruction(state, ins);
21051         } while(ins != first);
21052         
21053         print_blocks(state, __func__, state->dbgout);
21054 }
21055
21056 #if DEBUG_CONSISTENCY
21057 static void verify_uses(struct compile_state *state)
21058 {
21059         struct triple *first, *ins;
21060         struct triple_set *set;
21061         first = state->first;
21062         ins = first;
21063         do {
21064                 struct triple **expr;
21065                 expr = triple_rhs(state, ins, 0);
21066                 for(; expr; expr = triple_rhs(state, ins, expr)) {
21067                         struct triple *rhs;
21068                         rhs = *expr;
21069                         for(set = rhs?rhs->use:0; set; set = set->next) {
21070                                 if (set->member == ins) {
21071                                         break;
21072                                 }
21073                         }
21074                         if (!set) {
21075                                 internal_error(state, ins, "rhs not used");
21076                         }
21077                 }
21078                 expr = triple_lhs(state, ins, 0);
21079                 for(; expr; expr = triple_lhs(state, ins, expr)) {
21080                         struct triple *lhs;
21081                         lhs = *expr;
21082                         for(set =  lhs?lhs->use:0; set; set = set->next) {
21083                                 if (set->member == ins) {
21084                                         break;
21085                                 }
21086                         }
21087                         if (!set) {
21088                                 internal_error(state, ins, "lhs not used");
21089                         }
21090                 }
21091                 expr = triple_misc(state, ins, 0);
21092                 if (ins->op != OP_PHI) {
21093                         for(; expr; expr = triple_targ(state, ins, expr)) {
21094                                 struct triple *misc;
21095                                 misc = *expr;
21096                                 for(set = misc?misc->use:0; set; set = set->next) {
21097                                         if (set->member == ins) {
21098                                                 break;
21099                                         }
21100                                 }
21101                                 if (!set) {
21102                                         internal_error(state, ins, "misc not used");
21103                                 }
21104                         }
21105                 }
21106                 if (!triple_is_ret(state, ins)) {
21107                         expr = triple_targ(state, ins, 0);
21108                         for(; expr; expr = triple_targ(state, ins, expr)) {
21109                                 struct triple *targ;
21110                                 targ = *expr;
21111                                 for(set = targ?targ->use:0; set; set = set->next) {
21112                                         if (set->member == ins) {
21113                                                 break;
21114                                         }
21115                                 }
21116                                 if (!set) {
21117                                         internal_error(state, ins, "targ not used");
21118                                 }
21119                         }
21120                 }
21121                 ins = ins->next;
21122         } while(ins != first);
21123         
21124 }
21125 static void verify_blocks_present(struct compile_state *state)
21126 {
21127         struct triple *first, *ins;
21128         if (!state->bb.first_block) {
21129                 return;
21130         }
21131         first = state->first;
21132         ins = first;
21133         do {
21134                 valid_ins(state, ins);
21135                 if (triple_stores_block(state, ins)) {
21136                         if (!ins->u.block) {
21137                                 internal_error(state, ins, 
21138                                         "%p not in a block?", ins);
21139                         }
21140                 }
21141                 ins = ins->next;
21142         } while(ins != first);
21143         
21144         
21145 }
21146
21147 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21148 {
21149         struct block_set *bedge;
21150         struct block *targ;
21151         targ = block_of_triple(state, edge);
21152         for(bedge = block->edges; bedge; bedge = bedge->next) {
21153                 if (bedge->member == targ) {
21154                         return 1;
21155                 }
21156         }
21157         return 0;
21158 }
21159
21160 static void verify_blocks(struct compile_state *state)
21161 {
21162         struct triple *ins;
21163         struct block *block;
21164         int blocks;
21165         block = state->bb.first_block;
21166         if (!block) {
21167                 return;
21168         }
21169         blocks = 0;
21170         do {
21171                 int users;
21172                 struct block_set *user, *edge;
21173                 blocks++;
21174                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21175                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21176                                 internal_error(state, ins, "inconsitent block specified");
21177                         }
21178                         valid_ins(state, ins);
21179                 }
21180                 users = 0;
21181                 for(user = block->use; user; user = user->next) {
21182                         users++;
21183                         if (!user->member->first) {
21184                                 internal_error(state, block->first, "user is empty");
21185                         }
21186                         if ((block == state->bb.last_block) &&
21187                                 (user->member == state->bb.first_block)) {
21188                                 continue;
21189                         }
21190                         for(edge = user->member->edges; edge; edge = edge->next) {
21191                                 if (edge->member == block) {
21192                                         break;
21193                                 }
21194                         }
21195                         if (!edge) {
21196                                 internal_error(state, user->member->first,
21197                                         "user does not use block");
21198                         }
21199                 }
21200                 if (triple_is_branch(state, block->last)) {
21201                         struct triple **expr;
21202                         expr = triple_edge_targ(state, block->last, 0);
21203                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21204                                 if (*expr && !edge_present(state, block, *expr)) {
21205                                         internal_error(state, block->last, "no edge to targ");
21206                                 }
21207                         }
21208                 }
21209                 if (!triple_is_ubranch(state, block->last) &&
21210                         (block != state->bb.last_block) &&
21211                         !edge_present(state, block, block->last->next)) {
21212                         internal_error(state, block->last, "no edge to block->last->next");
21213                 }
21214                 for(edge = block->edges; edge; edge = edge->next) {
21215                         for(user = edge->member->use; user; user = user->next) {
21216                                 if (user->member == block) {
21217                                         break;
21218                                 }
21219                         }
21220                         if (!user || user->member != block) {
21221                                 internal_error(state, block->first,
21222                                         "block does not use edge");
21223                         }
21224                         if (!edge->member->first) {
21225                                 internal_error(state, block->first, "edge block is empty");
21226                         }
21227                 }
21228                 if (block->users != users) {
21229                         internal_error(state, block->first, 
21230                                 "computed users %d != stored users %d",
21231                                 users, block->users);
21232                 }
21233                 if (!triple_stores_block(state, block->last->next)) {
21234                         internal_error(state, block->last->next, 
21235                                 "cannot find next block");
21236                 }
21237                 block = block->last->next->u.block;
21238                 if (!block) {
21239                         internal_error(state, block->last->next,
21240                                 "bad next block");
21241                 }
21242         } while(block != state->bb.first_block);
21243         if (blocks != state->bb.last_vertex) {
21244                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21245                         blocks, state->bb.last_vertex);
21246         }
21247 }
21248
21249 static void verify_domination(struct compile_state *state)
21250 {
21251         struct triple *first, *ins;
21252         struct triple_set *set;
21253         if (!state->bb.first_block) {
21254                 return;
21255         }
21256         
21257         first = state->first;
21258         ins = first;
21259         do {
21260                 for(set = ins->use; set; set = set->next) {
21261                         struct triple **slot;
21262                         struct triple *use_point;
21263                         int i, zrhs;
21264                         use_point = 0;
21265                         zrhs = set->member->rhs;
21266                         slot = &RHS(set->member, 0);
21267                         /* See if the use is on the right hand side */
21268                         for(i = 0; i < zrhs; i++) {
21269                                 if (slot[i] == ins) {
21270                                         break;
21271                                 }
21272                         }
21273                         if (i < zrhs) {
21274                                 use_point = set->member;
21275                                 if (set->member->op == OP_PHI) {
21276                                         struct block_set *bset;
21277                                         int edge;
21278                                         bset = set->member->u.block->use;
21279                                         for(edge = 0; bset && (edge < i); edge++) {
21280                                                 bset = bset->next;
21281                                         }
21282                                         if (!bset) {
21283                                                 internal_error(state, set->member, 
21284                                                         "no edge for phi rhs %d", i);
21285                                         }
21286                                         use_point = bset->member->last;
21287                                 }
21288                         }
21289                         if (use_point &&
21290                                 !tdominates(state, ins, use_point)) {
21291                                 if (is_const(ins)) {
21292                                         internal_warning(state, ins, 
21293                                         "non dominated rhs use point %p?", use_point);
21294                                 }
21295                                 else {
21296                                         internal_error(state, ins, 
21297                                                 "non dominated rhs use point %p?", use_point);
21298                                 }
21299                         }
21300                 }
21301                 ins = ins->next;
21302         } while(ins != first);
21303 }
21304
21305 static void verify_rhs(struct compile_state *state)
21306 {
21307         struct triple *first, *ins;
21308         first = state->first;
21309         ins = first;
21310         do {
21311                 struct triple **slot;
21312                 int zrhs, i;
21313                 zrhs = ins->rhs;
21314                 slot = &RHS(ins, 0);
21315                 for(i = 0; i < zrhs; i++) {
21316                         if (slot[i] == 0) {
21317                                 internal_error(state, ins,
21318                                         "missing rhs %d on %s",
21319                                         i, tops(ins->op));
21320                         }
21321                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21322                                 internal_error(state, ins,
21323                                         "ins == rhs[%d] on %s",
21324                                         i, tops(ins->op));
21325                         }
21326                 }
21327                 ins = ins->next;
21328         } while(ins != first);
21329 }
21330
21331 static void verify_piece(struct compile_state *state)
21332 {
21333         struct triple *first, *ins;
21334         first = state->first;
21335         ins = first;
21336         do {
21337                 struct triple *ptr;
21338                 int lhs, i;
21339                 lhs = ins->lhs;
21340                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21341                         if (ptr != LHS(ins, i)) {
21342                                 internal_error(state, ins, "malformed lhs on %s",
21343                                         tops(ins->op));
21344                         }
21345                         if (ptr->op != OP_PIECE) {
21346                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21347                                         tops(ptr->op), i, tops(ins->op));
21348                         }
21349                         if (ptr->u.cval != i) {
21350                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21351                                         ptr->u.cval, i);
21352                         }
21353                 }
21354                 ins = ins->next;
21355         } while(ins != first);
21356 }
21357
21358 static void verify_ins_colors(struct compile_state *state)
21359 {
21360         struct triple *first, *ins;
21361         
21362         first = state->first;
21363         ins = first;
21364         do {
21365                 ins = ins->next;
21366         } while(ins != first);
21367 }
21368
21369 static void verify_unknown(struct compile_state *state)
21370 {
21371         struct triple *first, *ins;
21372         if (    (unknown_triple.next != &unknown_triple) ||
21373                 (unknown_triple.prev != &unknown_triple) ||
21374 #if 0
21375                 (unknown_triple.use != 0) ||
21376 #endif
21377                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21378                 (unknown_triple.lhs != 0) ||
21379                 (unknown_triple.rhs != 0) ||
21380                 (unknown_triple.misc != 0) ||
21381                 (unknown_triple.targ != 0) ||
21382                 (unknown_triple.template_id != 0) ||
21383                 (unknown_triple.id != -1) ||
21384                 (unknown_triple.type != &unknown_type) ||
21385                 (unknown_triple.occurance != &dummy_occurance) ||
21386                 (unknown_triple.param[0] != 0) ||
21387                 (unknown_triple.param[1] != 0)) {
21388                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21389         }
21390         if (    (dummy_occurance.count != 2) ||
21391                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21392                 (strcmp(dummy_occurance.function, "") != 0) ||
21393                 (dummy_occurance.col != 0) ||
21394                 (dummy_occurance.parent != 0)) {
21395                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21396         }
21397         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21398                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21399         }
21400         first = state->first;
21401         ins = first;
21402         do {
21403                 int params, i;
21404                 if (ins == &unknown_triple) {
21405                         internal_error(state, ins, "unknown triple in list");
21406                 }
21407                 params = TRIPLE_SIZE(ins);
21408                 for(i = 0; i < params; i++) {
21409                         if (ins->param[i] == &unknown_triple) {
21410                                 internal_error(state, ins, "unknown triple used!");
21411                         }
21412                 }
21413                 ins = ins->next;
21414         } while(ins != first);
21415 }
21416
21417 static void verify_types(struct compile_state *state)
21418 {
21419         struct triple *first, *ins;
21420         first = state->first;
21421         ins = first;
21422         do {
21423                 struct type *invalid;
21424                 invalid = invalid_type(state, ins->type);
21425                 if (invalid) {
21426                         FILE *fp = state->errout;
21427                         fprintf(fp, "type: ");
21428                         name_of(fp, ins->type);
21429                         fprintf(fp, "\n");
21430                         fprintf(fp, "invalid type: ");
21431                         name_of(fp, invalid);
21432                         fprintf(fp, "\n");
21433                         internal_error(state, ins, "invalid ins type");
21434                 }
21435         } while(ins != first);
21436 }
21437
21438 static void verify_copy(struct compile_state *state)
21439 {
21440         struct triple *first, *ins, *next;
21441         first = state->first;
21442         next = ins = first;
21443         do {
21444                 ins = next;
21445                 next = ins->next;
21446                 if (ins->op != OP_COPY) {
21447                         continue;
21448                 }
21449                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21450                         FILE *fp = state->errout;
21451                         fprintf(fp, "src type: ");
21452                         name_of(fp, RHS(ins, 0)->type);
21453                         fprintf(fp, "\n");
21454                         fprintf(fp, "dst type: ");
21455                         name_of(fp, ins->type);
21456                         fprintf(fp, "\n");
21457                         internal_error(state, ins, "type mismatch in copy");
21458                 }
21459         } while(next != first);
21460 }
21461
21462 static void verify_consistency(struct compile_state *state)
21463 {
21464         verify_unknown(state);
21465         verify_uses(state);
21466         verify_blocks_present(state);
21467         verify_blocks(state);
21468         verify_domination(state);
21469         verify_rhs(state);
21470         verify_piece(state);
21471         verify_ins_colors(state);
21472         verify_types(state);
21473         verify_copy(state);
21474         if (state->compiler->debug & DEBUG_VERIFICATION) {
21475                 fprintf(state->dbgout, "consistency verified\n");
21476         }
21477 }
21478 #else 
21479 static void verify_consistency(struct compile_state *state) {}
21480 #endif /* DEBUG_CONSISTENCY */
21481
21482 static void optimize(struct compile_state *state)
21483 {
21484         /* Join all of the functions into one giant function */
21485         join_functions(state);
21486
21487         /* Dump what the instruction graph intially looks like */
21488         print_triples(state);
21489
21490         /* Replace structures with simpler data types */
21491         decompose_compound_types(state);
21492         print_triples(state);
21493
21494         verify_consistency(state);
21495         /* Analyze the intermediate code */
21496         state->bb.first = state->first;
21497         analyze_basic_blocks(state, &state->bb);
21498
21499         /* Transform the code to ssa form. */
21500         /*
21501          * The transformation to ssa form puts a phi function
21502          * on each of edge of a dominance frontier where that
21503          * phi function might be needed.  At -O2 if we don't
21504          * eleminate the excess phi functions we can get an
21505          * exponential code size growth.  So I kill the extra
21506          * phi functions early and I kill them often.
21507          */
21508         transform_to_ssa_form(state);
21509         verify_consistency(state);
21510
21511         /* Remove dead code */
21512         eliminate_inefectual_code(state);
21513         verify_consistency(state);
21514
21515         /* Do strength reduction and simple constant optimizations */
21516         simplify_all(state);
21517         verify_consistency(state);
21518         /* Propogate constants throughout the code */
21519         scc_transform(state);
21520         verify_consistency(state);
21521 #warning "WISHLIST implement single use constants (least possible register pressure)"
21522 #warning "WISHLIST implement induction variable elimination"
21523         /* Select architecture instructions and an initial partial
21524          * coloring based on architecture constraints.
21525          */
21526         transform_to_arch_instructions(state);
21527         verify_consistency(state);
21528
21529         /* Remove dead code */
21530         eliminate_inefectual_code(state);
21531         verify_consistency(state);
21532
21533         /* Color all of the variables to see if they will fit in registers */
21534         insert_copies_to_phi(state);
21535         verify_consistency(state);
21536
21537         insert_mandatory_copies(state);
21538         verify_consistency(state);
21539
21540         allocate_registers(state);
21541         verify_consistency(state);
21542
21543         /* Remove the optimization information.
21544          * This is more to check for memory consistency than to free memory.
21545          */
21546         free_basic_blocks(state, &state->bb);
21547 }
21548
21549 static void print_op_asm(struct compile_state *state,
21550         struct triple *ins, FILE *fp)
21551 {
21552         struct asm_info *info;
21553         const char *ptr;
21554         unsigned lhs, rhs, i;
21555         info = ins->u.ainfo;
21556         lhs = ins->lhs;
21557         rhs = ins->rhs;
21558         /* Don't count the clobbers in lhs */
21559         for(i = 0; i < lhs; i++) {
21560                 if (LHS(ins, i)->type == &void_type) {
21561                         break;
21562                 }
21563         }
21564         lhs = i;
21565         fprintf(fp, "#ASM\n");
21566         fputc('\t', fp);
21567         for(ptr = info->str; *ptr; ptr++) {
21568                 char *next;
21569                 unsigned long param;
21570                 struct triple *piece;
21571                 if (*ptr != '%') {
21572                         fputc(*ptr, fp);
21573                         continue;
21574                 }
21575                 ptr++;
21576                 if (*ptr == '%') {
21577                         fputc('%', fp);
21578                         continue;
21579                 }
21580                 param = strtoul(ptr, &next, 10);
21581                 if (ptr == next) {
21582                         error(state, ins, "Invalid asm template");
21583                 }
21584                 if (param >= (lhs + rhs)) {
21585                         error(state, ins, "Invalid param %%%u in asm template",
21586                                 param);
21587                 }
21588                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21589                 fprintf(fp, "%s", 
21590                         arch_reg_str(ID_REG(piece->id)));
21591                 ptr = next -1;
21592         }
21593         fprintf(fp, "\n#NOT ASM\n");
21594 }
21595
21596
21597 /* Only use the low x86 byte registers.  This allows me
21598  * allocate the entire register when a byte register is used.
21599  */
21600 #define X86_4_8BIT_GPRS 1
21601
21602 /* x86 featrues */
21603 #define X86_MMX_REGS  (1<<0)
21604 #define X86_XMM_REGS  (1<<1)
21605 #define X86_NOOP_COPY (1<<2)
21606
21607 /* The x86 register classes */
21608 #define REGC_FLAGS       0
21609 #define REGC_GPR8        1
21610 #define REGC_GPR16       2
21611 #define REGC_GPR32       3
21612 #define REGC_DIVIDEND64  4
21613 #define REGC_DIVIDEND32  5
21614 #define REGC_MMX         6
21615 #define REGC_XMM         7
21616 #define REGC_GPR32_8     8
21617 #define REGC_GPR16_8     9
21618 #define REGC_GPR8_LO    10
21619 #define REGC_IMM32      11
21620 #define REGC_IMM16      12
21621 #define REGC_IMM8       13
21622 #define LAST_REGC  REGC_IMM8
21623 #if LAST_REGC >= MAX_REGC
21624 #error "MAX_REGC is to low"
21625 #endif
21626
21627 /* Register class masks */
21628 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21629 #define REGCM_GPR8       (1 << REGC_GPR8)
21630 #define REGCM_GPR16      (1 << REGC_GPR16)
21631 #define REGCM_GPR32      (1 << REGC_GPR32)
21632 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21633 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21634 #define REGCM_MMX        (1 << REGC_MMX)
21635 #define REGCM_XMM        (1 << REGC_XMM)
21636 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21637 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21638 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21639 #define REGCM_IMM32      (1 << REGC_IMM32)
21640 #define REGCM_IMM16      (1 << REGC_IMM16)
21641 #define REGCM_IMM8       (1 << REGC_IMM8)
21642 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21643 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21644
21645 /* The x86 registers */
21646 #define REG_EFLAGS  2
21647 #define REGC_FLAGS_FIRST REG_EFLAGS
21648 #define REGC_FLAGS_LAST  REG_EFLAGS
21649 #define REG_AL      3
21650 #define REG_BL      4
21651 #define REG_CL      5
21652 #define REG_DL      6
21653 #define REG_AH      7
21654 #define REG_BH      8
21655 #define REG_CH      9
21656 #define REG_DH      10
21657 #define REGC_GPR8_LO_FIRST REG_AL
21658 #define REGC_GPR8_LO_LAST  REG_DL
21659 #define REGC_GPR8_FIRST  REG_AL
21660 #define REGC_GPR8_LAST   REG_DH
21661 #define REG_AX     11
21662 #define REG_BX     12
21663 #define REG_CX     13
21664 #define REG_DX     14
21665 #define REG_SI     15
21666 #define REG_DI     16
21667 #define REG_BP     17
21668 #define REG_SP     18
21669 #define REGC_GPR16_FIRST REG_AX
21670 #define REGC_GPR16_LAST  REG_SP
21671 #define REG_EAX    19
21672 #define REG_EBX    20
21673 #define REG_ECX    21
21674 #define REG_EDX    22
21675 #define REG_ESI    23
21676 #define REG_EDI    24
21677 #define REG_EBP    25
21678 #define REG_ESP    26
21679 #define REGC_GPR32_FIRST REG_EAX
21680 #define REGC_GPR32_LAST  REG_ESP
21681 #define REG_EDXEAX 27
21682 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21683 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21684 #define REG_DXAX   28
21685 #define REGC_DIVIDEND32_FIRST REG_DXAX
21686 #define REGC_DIVIDEND32_LAST  REG_DXAX
21687 #define REG_MMX0   29
21688 #define REG_MMX1   30
21689 #define REG_MMX2   31
21690 #define REG_MMX3   32
21691 #define REG_MMX4   33
21692 #define REG_MMX5   34
21693 #define REG_MMX6   35
21694 #define REG_MMX7   36
21695 #define REGC_MMX_FIRST REG_MMX0
21696 #define REGC_MMX_LAST  REG_MMX7
21697 #define REG_XMM0   37
21698 #define REG_XMM1   38
21699 #define REG_XMM2   39
21700 #define REG_XMM3   40
21701 #define REG_XMM4   41
21702 #define REG_XMM5   42
21703 #define REG_XMM6   43
21704 #define REG_XMM7   44
21705 #define REGC_XMM_FIRST REG_XMM0
21706 #define REGC_XMM_LAST  REG_XMM7
21707 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21708 #define LAST_REG   REG_XMM7
21709
21710 #define REGC_GPR32_8_FIRST REG_EAX
21711 #define REGC_GPR32_8_LAST  REG_EDX
21712 #define REGC_GPR16_8_FIRST REG_AX
21713 #define REGC_GPR16_8_LAST  REG_DX
21714
21715 #define REGC_IMM8_FIRST    -1
21716 #define REGC_IMM8_LAST     -1
21717 #define REGC_IMM16_FIRST   -2
21718 #define REGC_IMM16_LAST    -1
21719 #define REGC_IMM32_FIRST   -4
21720 #define REGC_IMM32_LAST    -1
21721
21722 #if LAST_REG >= MAX_REGISTERS
21723 #error "MAX_REGISTERS to low"
21724 #endif
21725
21726
21727 static unsigned regc_size[LAST_REGC +1] = {
21728         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21729         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21730         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21731         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21732         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21733         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21734         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21735         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21736         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21737         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21738         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21739         [REGC_IMM32]      = 0,
21740         [REGC_IMM16]      = 0,
21741         [REGC_IMM8]       = 0,
21742 };
21743
21744 static const struct {
21745         int first, last;
21746 } regcm_bound[LAST_REGC + 1] = {
21747         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21748         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21749         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21750         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21751         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21752         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21753         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21754         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21755         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21756         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21757         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21758         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21759         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21760         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21761 };
21762
21763 #if ARCH_INPUT_REGS != 4
21764 #error ARCH_INPUT_REGS size mismatch
21765 #endif
21766 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21767         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21768         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21769         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21770         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21771 };
21772
21773 #if ARCH_OUTPUT_REGS != 4
21774 #error ARCH_INPUT_REGS size mismatch
21775 #endif
21776 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21777         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21778         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21779         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21780         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21781 };
21782
21783 static void init_arch_state(struct arch_state *arch)
21784 {
21785         memset(arch, 0, sizeof(*arch));
21786         arch->features = 0;
21787 }
21788
21789 static const struct compiler_flag arch_flags[] = {
21790         { "mmx",       X86_MMX_REGS },
21791         { "sse",       X86_XMM_REGS },
21792         { "noop-copy", X86_NOOP_COPY },
21793         { 0,     0 },
21794 };
21795 static const struct compiler_flag arch_cpus[] = {
21796         { "i386", 0 },
21797         { "p2",   X86_MMX_REGS },
21798         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21799         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21800         { "k7",   X86_MMX_REGS },
21801         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21802         { "c3",   X86_MMX_REGS },
21803         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21804         {  0,     0 }
21805 };
21806 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21807 {
21808         int result;
21809         int act;
21810
21811         act = 1;
21812         result = -1;
21813         if (strncmp(flag, "no-", 3) == 0) {
21814                 flag += 3;
21815                 act = 0;
21816         }
21817         if (act && strncmp(flag, "cpu=", 4) == 0) {
21818                 flag += 4;
21819                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21820         }
21821         else {
21822                 result = set_flag(arch_flags, &arch->features, act, flag);
21823         }
21824         return result;
21825 }
21826
21827 static void arch_usage(FILE *fp)
21828 {
21829         flag_usage(fp, arch_flags, "-m", "-mno-");
21830         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21831 }
21832
21833 static unsigned arch_regc_size(struct compile_state *state, int class)
21834 {
21835         if ((class < 0) || (class > LAST_REGC)) {
21836                 return 0;
21837         }
21838         return regc_size[class];
21839 }
21840
21841 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21842 {
21843         /* See if two register classes may have overlapping registers */
21844         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21845                 REGCM_GPR32_8 | REGCM_GPR32 | 
21846                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21847
21848         /* Special case for the immediates */
21849         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21850                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21851                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21852                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21853                 return 0;
21854         }
21855         return (regcm1 & regcm2) ||
21856                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21857 }
21858
21859 static void arch_reg_equivs(
21860         struct compile_state *state, unsigned *equiv, int reg)
21861 {
21862         if ((reg < 0) || (reg > LAST_REG)) {
21863                 internal_error(state, 0, "invalid register");
21864         }
21865         *equiv++ = reg;
21866         switch(reg) {
21867         case REG_AL:
21868 #if X86_4_8BIT_GPRS
21869                 *equiv++ = REG_AH;
21870 #endif
21871                 *equiv++ = REG_AX;
21872                 *equiv++ = REG_EAX;
21873                 *equiv++ = REG_DXAX;
21874                 *equiv++ = REG_EDXEAX;
21875                 break;
21876         case REG_AH:
21877 #if X86_4_8BIT_GPRS
21878                 *equiv++ = REG_AL;
21879 #endif
21880                 *equiv++ = REG_AX;
21881                 *equiv++ = REG_EAX;
21882                 *equiv++ = REG_DXAX;
21883                 *equiv++ = REG_EDXEAX;
21884                 break;
21885         case REG_BL:  
21886 #if X86_4_8BIT_GPRS
21887                 *equiv++ = REG_BH;
21888 #endif
21889                 *equiv++ = REG_BX;
21890                 *equiv++ = REG_EBX;
21891                 break;
21892
21893         case REG_BH:
21894 #if X86_4_8BIT_GPRS
21895                 *equiv++ = REG_BL;
21896 #endif
21897                 *equiv++ = REG_BX;
21898                 *equiv++ = REG_EBX;
21899                 break;
21900         case REG_CL:
21901 #if X86_4_8BIT_GPRS
21902                 *equiv++ = REG_CH;
21903 #endif
21904                 *equiv++ = REG_CX;
21905                 *equiv++ = REG_ECX;
21906                 break;
21907
21908         case REG_CH:
21909 #if X86_4_8BIT_GPRS
21910                 *equiv++ = REG_CL;
21911 #endif
21912                 *equiv++ = REG_CX;
21913                 *equiv++ = REG_ECX;
21914                 break;
21915         case REG_DL:
21916 #if X86_4_8BIT_GPRS
21917                 *equiv++ = REG_DH;
21918 #endif
21919                 *equiv++ = REG_DX;
21920                 *equiv++ = REG_EDX;
21921                 *equiv++ = REG_DXAX;
21922                 *equiv++ = REG_EDXEAX;
21923                 break;
21924         case REG_DH:
21925 #if X86_4_8BIT_GPRS
21926                 *equiv++ = REG_DL;
21927 #endif
21928                 *equiv++ = REG_DX;
21929                 *equiv++ = REG_EDX;
21930                 *equiv++ = REG_DXAX;
21931                 *equiv++ = REG_EDXEAX;
21932                 break;
21933         case REG_AX:
21934                 *equiv++ = REG_AL;
21935                 *equiv++ = REG_AH;
21936                 *equiv++ = REG_EAX;
21937                 *equiv++ = REG_DXAX;
21938                 *equiv++ = REG_EDXEAX;
21939                 break;
21940         case REG_BX:
21941                 *equiv++ = REG_BL;
21942                 *equiv++ = REG_BH;
21943                 *equiv++ = REG_EBX;
21944                 break;
21945         case REG_CX:  
21946                 *equiv++ = REG_CL;
21947                 *equiv++ = REG_CH;
21948                 *equiv++ = REG_ECX;
21949                 break;
21950         case REG_DX:  
21951                 *equiv++ = REG_DL;
21952                 *equiv++ = REG_DH;
21953                 *equiv++ = REG_EDX;
21954                 *equiv++ = REG_DXAX;
21955                 *equiv++ = REG_EDXEAX;
21956                 break;
21957         case REG_SI:  
21958                 *equiv++ = REG_ESI;
21959                 break;
21960         case REG_DI:
21961                 *equiv++ = REG_EDI;
21962                 break;
21963         case REG_BP:
21964                 *equiv++ = REG_EBP;
21965                 break;
21966         case REG_SP:
21967                 *equiv++ = REG_ESP;
21968                 break;
21969         case REG_EAX:
21970                 *equiv++ = REG_AL;
21971                 *equiv++ = REG_AH;
21972                 *equiv++ = REG_AX;
21973                 *equiv++ = REG_DXAX;
21974                 *equiv++ = REG_EDXEAX;
21975                 break;
21976         case REG_EBX:
21977                 *equiv++ = REG_BL;
21978                 *equiv++ = REG_BH;
21979                 *equiv++ = REG_BX;
21980                 break;
21981         case REG_ECX:
21982                 *equiv++ = REG_CL;
21983                 *equiv++ = REG_CH;
21984                 *equiv++ = REG_CX;
21985                 break;
21986         case REG_EDX:
21987                 *equiv++ = REG_DL;
21988                 *equiv++ = REG_DH;
21989                 *equiv++ = REG_DX;
21990                 *equiv++ = REG_DXAX;
21991                 *equiv++ = REG_EDXEAX;
21992                 break;
21993         case REG_ESI: 
21994                 *equiv++ = REG_SI;
21995                 break;
21996         case REG_EDI: 
21997                 *equiv++ = REG_DI;
21998                 break;
21999         case REG_EBP: 
22000                 *equiv++ = REG_BP;
22001                 break;
22002         case REG_ESP: 
22003                 *equiv++ = REG_SP;
22004                 break;
22005         case REG_DXAX: 
22006                 *equiv++ = REG_AL;
22007                 *equiv++ = REG_AH;
22008                 *equiv++ = REG_DL;
22009                 *equiv++ = REG_DH;
22010                 *equiv++ = REG_AX;
22011                 *equiv++ = REG_DX;
22012                 *equiv++ = REG_EAX;
22013                 *equiv++ = REG_EDX;
22014                 *equiv++ = REG_EDXEAX;
22015                 break;
22016         case REG_EDXEAX: 
22017                 *equiv++ = REG_AL;
22018                 *equiv++ = REG_AH;
22019                 *equiv++ = REG_DL;
22020                 *equiv++ = REG_DH;
22021                 *equiv++ = REG_AX;
22022                 *equiv++ = REG_DX;
22023                 *equiv++ = REG_EAX;
22024                 *equiv++ = REG_EDX;
22025                 *equiv++ = REG_DXAX;
22026                 break;
22027         }
22028         *equiv++ = REG_UNSET; 
22029 }
22030
22031 static unsigned arch_avail_mask(struct compile_state *state)
22032 {
22033         unsigned avail_mask;
22034         /* REGCM_GPR8 is not available */
22035         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
22036                 REGCM_GPR32 | REGCM_GPR32_8 | 
22037                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22038                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
22039         if (state->arch->features & X86_MMX_REGS) {
22040                 avail_mask |= REGCM_MMX;
22041         }
22042         if (state->arch->features & X86_XMM_REGS) {
22043                 avail_mask |= REGCM_XMM;
22044         }
22045         return avail_mask;
22046 }
22047
22048 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
22049 {
22050         unsigned mask, result;
22051         int class, class2;
22052         result = regcm;
22053
22054         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
22055                 if ((result & mask) == 0) {
22056                         continue;
22057                 }
22058                 if (class > LAST_REGC) {
22059                         result &= ~mask;
22060                 }
22061                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
22062                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
22063                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
22064                                 result |= (1 << class2);
22065                         }
22066                 }
22067         }
22068         result &= arch_avail_mask(state);
22069         return result;
22070 }
22071
22072 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
22073 {
22074         /* Like arch_regcm_normalize except immediate register classes are excluded */
22075         regcm = arch_regcm_normalize(state, regcm);
22076         /* Remove the immediate register classes */
22077         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22078         return regcm;
22079         
22080 }
22081
22082 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
22083 {
22084         unsigned mask;
22085         int class;
22086         mask = 0;
22087         for(class = 0; class <= LAST_REGC; class++) {
22088                 if ((reg >= regcm_bound[class].first) &&
22089                         (reg <= regcm_bound[class].last)) {
22090                         mask |= (1 << class);
22091                 }
22092         }
22093         if (!mask) {
22094                 internal_error(state, 0, "reg %d not in any class", reg);
22095         }
22096         return mask;
22097 }
22098
22099 static struct reg_info arch_reg_constraint(
22100         struct compile_state *state, struct type *type, const char *constraint)
22101 {
22102         static const struct {
22103                 char class;
22104                 unsigned int mask;
22105                 unsigned int reg;
22106         } constraints[] = {
22107                 { 'r', REGCM_GPR32,   REG_UNSET },
22108                 { 'g', REGCM_GPR32,   REG_UNSET },
22109                 { 'p', REGCM_GPR32,   REG_UNSET },
22110                 { 'q', REGCM_GPR8_LO, REG_UNSET },
22111                 { 'Q', REGCM_GPR32_8, REG_UNSET },
22112                 { 'x', REGCM_XMM,     REG_UNSET },
22113                 { 'y', REGCM_MMX,     REG_UNSET },
22114                 { 'a', REGCM_GPR32,   REG_EAX },
22115                 { 'b', REGCM_GPR32,   REG_EBX },
22116                 { 'c', REGCM_GPR32,   REG_ECX },
22117                 { 'd', REGCM_GPR32,   REG_EDX },
22118                 { 'D', REGCM_GPR32,   REG_EDI },
22119                 { 'S', REGCM_GPR32,   REG_ESI },
22120                 { '\0', 0, REG_UNSET },
22121         };
22122         unsigned int regcm;
22123         unsigned int mask, reg;
22124         struct reg_info result;
22125         const char *ptr;
22126         regcm = arch_type_to_regcm(state, type);
22127         reg = REG_UNSET;
22128         mask = 0;
22129         for(ptr = constraint; *ptr; ptr++) {
22130                 int i;
22131                 if (*ptr ==  ' ') {
22132                         continue;
22133                 }
22134                 for(i = 0; constraints[i].class != '\0'; i++) {
22135                         if (constraints[i].class == *ptr) {
22136                                 break;
22137                         }
22138                 }
22139                 if (constraints[i].class == '\0') {
22140                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22141                         break;
22142                 }
22143                 if ((constraints[i].mask & regcm) == 0) {
22144                         error(state, 0, "invalid register class %c specified",
22145                                 *ptr);
22146                 }
22147                 mask |= constraints[i].mask;
22148                 if (constraints[i].reg != REG_UNSET) {
22149                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22150                                 error(state, 0, "Only one register may be specified");
22151                         }
22152                         reg = constraints[i].reg;
22153                 }
22154         }
22155         result.reg = reg;
22156         result.regcm = mask;
22157         return result;
22158 }
22159
22160 static struct reg_info arch_reg_clobber(
22161         struct compile_state *state, const char *clobber)
22162 {
22163         struct reg_info result;
22164         if (strcmp(clobber, "memory") == 0) {
22165                 result.reg = REG_UNSET;
22166                 result.regcm = 0;
22167         }
22168         else if (strcmp(clobber, "eax") == 0) {
22169                 result.reg = REG_EAX;
22170                 result.regcm = REGCM_GPR32;
22171         }
22172         else if (strcmp(clobber, "ebx") == 0) {
22173                 result.reg = REG_EBX;
22174                 result.regcm = REGCM_GPR32;
22175         }
22176         else if (strcmp(clobber, "ecx") == 0) {
22177                 result.reg = REG_ECX;
22178                 result.regcm = REGCM_GPR32;
22179         }
22180         else if (strcmp(clobber, "edx") == 0) {
22181                 result.reg = REG_EDX;
22182                 result.regcm = REGCM_GPR32;
22183         }
22184         else if (strcmp(clobber, "esi") == 0) {
22185                 result.reg = REG_ESI;
22186                 result.regcm = REGCM_GPR32;
22187         }
22188         else if (strcmp(clobber, "edi") == 0) {
22189                 result.reg = REG_EDI;
22190                 result.regcm = REGCM_GPR32;
22191         }
22192         else if (strcmp(clobber, "ebp") == 0) {
22193                 result.reg = REG_EBP;
22194                 result.regcm = REGCM_GPR32;
22195         }
22196         else if (strcmp(clobber, "esp") == 0) {
22197                 result.reg = REG_ESP;
22198                 result.regcm = REGCM_GPR32;
22199         }
22200         else if (strcmp(clobber, "cc") == 0) {
22201                 result.reg = REG_EFLAGS;
22202                 result.regcm = REGCM_FLAGS;
22203         }
22204         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22205                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22206                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22207                 result.regcm = REGCM_XMM;
22208         }
22209         else if ((strncmp(clobber, "mm", 2) == 0) &&
22210                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22211                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22212                 result.regcm = REGCM_MMX;
22213         }
22214         else {
22215                 error(state, 0, "unknown register name `%s' in asm",
22216                         clobber);
22217                 result.reg = REG_UNSET;
22218                 result.regcm = 0;
22219         }
22220         return result;
22221 }
22222
22223 static int do_select_reg(struct compile_state *state, 
22224         char *used, int reg, unsigned classes)
22225 {
22226         unsigned mask;
22227         if (used[reg]) {
22228                 return REG_UNSET;
22229         }
22230         mask = arch_reg_regcm(state, reg);
22231         return (classes & mask) ? reg : REG_UNSET;
22232 }
22233
22234 static int arch_select_free_register(
22235         struct compile_state *state, char *used, int classes)
22236 {
22237         /* Live ranges with the most neighbors are colored first.
22238          *
22239          * Generally it does not matter which colors are given
22240          * as the register allocator attempts to color live ranges
22241          * in an order where you are guaranteed not to run out of colors.
22242          *
22243          * Occasionally the register allocator cannot find an order
22244          * of register selection that will find a free color.  To
22245          * increase the odds the register allocator will work when
22246          * it guesses first give out registers from register classes
22247          * least likely to run out of registers.
22248          * 
22249          */
22250         int i, reg;
22251         reg = REG_UNSET;
22252         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22253                 reg = do_select_reg(state, used, i, classes);
22254         }
22255         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22256                 reg = do_select_reg(state, used, i, classes);
22257         }
22258         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22259                 reg = do_select_reg(state, used, i, classes);
22260         }
22261         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22262                 reg = do_select_reg(state, used, i, classes);
22263         }
22264         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22265                 reg = do_select_reg(state, used, i, classes);
22266         }
22267         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22268                 reg = do_select_reg(state, used, i, classes);
22269         }
22270         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22271                 reg = do_select_reg(state, used, i, classes);
22272         }
22273         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22274                 reg = do_select_reg(state, used, i, classes);
22275         }
22276         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22277                 reg = do_select_reg(state, used, i, classes);
22278         }
22279         return reg;
22280 }
22281
22282
22283 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22284 {
22285 #warning "FIXME force types smaller (if legal) before I get here"
22286         unsigned mask;
22287         mask = 0;
22288         switch(type->type & TYPE_MASK) {
22289         case TYPE_ARRAY:
22290         case TYPE_VOID: 
22291                 mask = 0; 
22292                 break;
22293         case TYPE_CHAR:
22294         case TYPE_UCHAR:
22295                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22296                         REGCM_GPR16 | REGCM_GPR16_8 | 
22297                         REGCM_GPR32 | REGCM_GPR32_8 |
22298                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22299                         REGCM_MMX | REGCM_XMM |
22300                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22301                 break;
22302         case TYPE_SHORT:
22303         case TYPE_USHORT:
22304                 mask =  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;
22309                 break;
22310         case TYPE_ENUM:
22311         case TYPE_INT:
22312         case TYPE_UINT:
22313         case TYPE_LONG:
22314         case TYPE_ULONG:
22315         case TYPE_POINTER:
22316                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22317                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22318                         REGCM_MMX | REGCM_XMM |
22319                         REGCM_IMM32;
22320                 break;
22321         case TYPE_JOIN:
22322         case TYPE_UNION:
22323                 mask = arch_type_to_regcm(state, type->left);
22324                 break;
22325         case TYPE_OVERLAP:
22326                 mask = arch_type_to_regcm(state, type->left) &
22327                         arch_type_to_regcm(state, type->right);
22328                 break;
22329         case TYPE_BITFIELD:
22330                 mask = arch_type_to_regcm(state, type->left);
22331                 break;
22332         default:
22333                 fprintf(state->errout, "type: ");
22334                 name_of(state->errout, type);
22335                 fprintf(state->errout, "\n");
22336                 internal_error(state, 0, "no register class for type");
22337                 break;
22338         }
22339         mask = arch_regcm_normalize(state, mask);
22340         return mask;
22341 }
22342
22343 static int is_imm32(struct triple *imm)
22344 {
22345         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22346                 (imm->op == OP_ADDRCONST);
22347         
22348 }
22349 static int is_imm16(struct triple *imm)
22350 {
22351         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22352 }
22353 static int is_imm8(struct triple *imm)
22354 {
22355         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22356 }
22357
22358 static int get_imm32(struct triple *ins, struct triple **expr)
22359 {
22360         struct triple *imm;
22361         imm = *expr;
22362         while(imm->op == OP_COPY) {
22363                 imm = RHS(imm, 0);
22364         }
22365         if (!is_imm32(imm)) {
22366                 return 0;
22367         }
22368         unuse_triple(*expr, ins);
22369         use_triple(imm, ins);
22370         *expr = imm;
22371         return 1;
22372 }
22373
22374 static int get_imm8(struct triple *ins, struct triple **expr)
22375 {
22376         struct triple *imm;
22377         imm = *expr;
22378         while(imm->op == OP_COPY) {
22379                 imm = RHS(imm, 0);
22380         }
22381         if (!is_imm8(imm)) {
22382                 return 0;
22383         }
22384         unuse_triple(*expr, ins);
22385         use_triple(imm, ins);
22386         *expr = imm;
22387         return 1;
22388 }
22389
22390 #define TEMPLATE_NOP           0
22391 #define TEMPLATE_INTCONST8     1
22392 #define TEMPLATE_INTCONST32    2
22393 #define TEMPLATE_UNKNOWNVAL    3
22394 #define TEMPLATE_COPY8_REG     5
22395 #define TEMPLATE_COPY16_REG    6
22396 #define TEMPLATE_COPY32_REG    7
22397 #define TEMPLATE_COPY_IMM8     8
22398 #define TEMPLATE_COPY_IMM16    9
22399 #define TEMPLATE_COPY_IMM32   10
22400 #define TEMPLATE_PHI8         11
22401 #define TEMPLATE_PHI16        12
22402 #define TEMPLATE_PHI32        13
22403 #define TEMPLATE_STORE8       14
22404 #define TEMPLATE_STORE16      15
22405 #define TEMPLATE_STORE32      16
22406 #define TEMPLATE_LOAD8        17
22407 #define TEMPLATE_LOAD16       18
22408 #define TEMPLATE_LOAD32       19
22409 #define TEMPLATE_BINARY8_REG  20
22410 #define TEMPLATE_BINARY16_REG 21
22411 #define TEMPLATE_BINARY32_REG 22
22412 #define TEMPLATE_BINARY8_IMM  23
22413 #define TEMPLATE_BINARY16_IMM 24
22414 #define TEMPLATE_BINARY32_IMM 25
22415 #define TEMPLATE_SL8_CL       26
22416 #define TEMPLATE_SL16_CL      27
22417 #define TEMPLATE_SL32_CL      28
22418 #define TEMPLATE_SL8_IMM      29
22419 #define TEMPLATE_SL16_IMM     30
22420 #define TEMPLATE_SL32_IMM     31
22421 #define TEMPLATE_UNARY8       32
22422 #define TEMPLATE_UNARY16      33
22423 #define TEMPLATE_UNARY32      34
22424 #define TEMPLATE_CMP8_REG     35
22425 #define TEMPLATE_CMP16_REG    36
22426 #define TEMPLATE_CMP32_REG    37
22427 #define TEMPLATE_CMP8_IMM     38
22428 #define TEMPLATE_CMP16_IMM    39
22429 #define TEMPLATE_CMP32_IMM    40
22430 #define TEMPLATE_TEST8        41
22431 #define TEMPLATE_TEST16       42
22432 #define TEMPLATE_TEST32       43
22433 #define TEMPLATE_SET          44
22434 #define TEMPLATE_JMP          45
22435 #define TEMPLATE_RET          46
22436 #define TEMPLATE_INB_DX       47
22437 #define TEMPLATE_INB_IMM      48
22438 #define TEMPLATE_INW_DX       49
22439 #define TEMPLATE_INW_IMM      50
22440 #define TEMPLATE_INL_DX       51
22441 #define TEMPLATE_INL_IMM      52
22442 #define TEMPLATE_OUTB_DX      53
22443 #define TEMPLATE_OUTB_IMM     54
22444 #define TEMPLATE_OUTW_DX      55
22445 #define TEMPLATE_OUTW_IMM     56
22446 #define TEMPLATE_OUTL_DX      57
22447 #define TEMPLATE_OUTL_IMM     58
22448 #define TEMPLATE_BSF          59
22449 #define TEMPLATE_RDMSR        60
22450 #define TEMPLATE_WRMSR        61
22451 #define TEMPLATE_UMUL8        62
22452 #define TEMPLATE_UMUL16       63
22453 #define TEMPLATE_UMUL32       64
22454 #define TEMPLATE_DIV8         65
22455 #define TEMPLATE_DIV16        66
22456 #define TEMPLATE_DIV32        67
22457 #define LAST_TEMPLATE       TEMPLATE_DIV32
22458 #if LAST_TEMPLATE >= MAX_TEMPLATES
22459 #error "MAX_TEMPLATES to low"
22460 #endif
22461
22462 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22463 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22464 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22465
22466
22467 static struct ins_template templates[] = {
22468         [TEMPLATE_NOP]      = {
22469                 .lhs = { 
22470                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22471                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22472                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22473                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22474                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22475                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22476                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22477                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22478                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22479                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22480                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22481                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22482                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22483                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22484                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22485                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22486                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22487                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22488                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22489                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22490                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22491                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22492                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22493                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22494                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22495                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22496                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22497                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22498                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22499                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22500                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22501                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22502                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22503                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22504                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22505                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22506                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22507                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22508                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22509                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22510                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22511                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22512                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22513                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22514                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22515                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22516                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22517                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22518                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22519                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22520                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22521                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22522                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22523                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22524                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22525                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22526                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22527                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22528                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22529                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22530                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22531                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22532                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22533                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22534                 },
22535         },
22536         [TEMPLATE_INTCONST8] = { 
22537                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22538         },
22539         [TEMPLATE_INTCONST32] = { 
22540                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22541         },
22542         [TEMPLATE_UNKNOWNVAL] = {
22543                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22544         },
22545         [TEMPLATE_COPY8_REG] = {
22546                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22547                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22548         },
22549         [TEMPLATE_COPY16_REG] = {
22550                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22551                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22552         },
22553         [TEMPLATE_COPY32_REG] = {
22554                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22555                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22556         },
22557         [TEMPLATE_COPY_IMM8] = {
22558                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22559                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22560         },
22561         [TEMPLATE_COPY_IMM16] = {
22562                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22563                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22564         },
22565         [TEMPLATE_COPY_IMM32] = {
22566                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22567                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22568         },
22569         [TEMPLATE_PHI8] = { 
22570                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22571                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22572         },
22573         [TEMPLATE_PHI16] = { 
22574                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22575                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22576         },
22577         [TEMPLATE_PHI32] = { 
22578                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22579                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22580         },
22581         [TEMPLATE_STORE8] = {
22582                 .rhs = { 
22583                         [0] = { REG_UNSET, REGCM_GPR32 },
22584                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22585                 },
22586         },
22587         [TEMPLATE_STORE16] = {
22588                 .rhs = { 
22589                         [0] = { REG_UNSET, REGCM_GPR32 },
22590                         [1] = { REG_UNSET, REGCM_GPR16 },
22591                 },
22592         },
22593         [TEMPLATE_STORE32] = {
22594                 .rhs = { 
22595                         [0] = { REG_UNSET, REGCM_GPR32 },
22596                         [1] = { REG_UNSET, REGCM_GPR32 },
22597                 },
22598         },
22599         [TEMPLATE_LOAD8] = {
22600                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22601                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22602         },
22603         [TEMPLATE_LOAD16] = {
22604                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22605                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22606         },
22607         [TEMPLATE_LOAD32] = {
22608                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22609                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22610         },
22611         [TEMPLATE_BINARY8_REG] = {
22612                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22613                 .rhs = { 
22614                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22615                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22616                 },
22617         },
22618         [TEMPLATE_BINARY16_REG] = {
22619                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22620                 .rhs = { 
22621                         [0] = { REG_VIRT0, REGCM_GPR16 },
22622                         [1] = { REG_UNSET, REGCM_GPR16 },
22623                 },
22624         },
22625         [TEMPLATE_BINARY32_REG] = {
22626                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22627                 .rhs = { 
22628                         [0] = { REG_VIRT0, REGCM_GPR32 },
22629                         [1] = { REG_UNSET, REGCM_GPR32 },
22630                 },
22631         },
22632         [TEMPLATE_BINARY8_IMM] = {
22633                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22634                 .rhs = { 
22635                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22636                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22637                 },
22638         },
22639         [TEMPLATE_BINARY16_IMM] = {
22640                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22641                 .rhs = { 
22642                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22643                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22644                 },
22645         },
22646         [TEMPLATE_BINARY32_IMM] = {
22647                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22648                 .rhs = { 
22649                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22650                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22651                 },
22652         },
22653         [TEMPLATE_SL8_CL] = {
22654                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22655                 .rhs = { 
22656                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22657                         [1] = { REG_CL, REGCM_GPR8_LO },
22658                 },
22659         },
22660         [TEMPLATE_SL16_CL] = {
22661                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22662                 .rhs = { 
22663                         [0] = { REG_VIRT0, REGCM_GPR16 },
22664                         [1] = { REG_CL, REGCM_GPR8_LO },
22665                 },
22666         },
22667         [TEMPLATE_SL32_CL] = {
22668                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22669                 .rhs = { 
22670                         [0] = { REG_VIRT0, REGCM_GPR32 },
22671                         [1] = { REG_CL, REGCM_GPR8_LO },
22672                 },
22673         },
22674         [TEMPLATE_SL8_IMM] = {
22675                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22676                 .rhs = { 
22677                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22678                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22679                 },
22680         },
22681         [TEMPLATE_SL16_IMM] = {
22682                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22683                 .rhs = { 
22684                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22685                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22686                 },
22687         },
22688         [TEMPLATE_SL32_IMM] = {
22689                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22690                 .rhs = { 
22691                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22692                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22693                 },
22694         },
22695         [TEMPLATE_UNARY8] = {
22696                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22697                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22698         },
22699         [TEMPLATE_UNARY16] = {
22700                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22701                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22702         },
22703         [TEMPLATE_UNARY32] = {
22704                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22705                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22706         },
22707         [TEMPLATE_CMP8_REG] = {
22708                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22709                 .rhs = {
22710                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22711                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22712                 },
22713         },
22714         [TEMPLATE_CMP16_REG] = {
22715                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22716                 .rhs = {
22717                         [0] = { REG_UNSET, REGCM_GPR16 },
22718                         [1] = { REG_UNSET, REGCM_GPR16 },
22719                 },
22720         },
22721         [TEMPLATE_CMP32_REG] = {
22722                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22723                 .rhs = {
22724                         [0] = { REG_UNSET, REGCM_GPR32 },
22725                         [1] = { REG_UNSET, REGCM_GPR32 },
22726                 },
22727         },
22728         [TEMPLATE_CMP8_IMM] = {
22729                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22730                 .rhs = {
22731                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22732                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22733                 },
22734         },
22735         [TEMPLATE_CMP16_IMM] = {
22736                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22737                 .rhs = {
22738                         [0] = { REG_UNSET, REGCM_GPR16 },
22739                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22740                 },
22741         },
22742         [TEMPLATE_CMP32_IMM] = {
22743                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22744                 .rhs = {
22745                         [0] = { REG_UNSET, REGCM_GPR32 },
22746                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22747                 },
22748         },
22749         [TEMPLATE_TEST8] = {
22750                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22751                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22752         },
22753         [TEMPLATE_TEST16] = {
22754                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22755                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22756         },
22757         [TEMPLATE_TEST32] = {
22758                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22759                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22760         },
22761         [TEMPLATE_SET] = {
22762                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22763                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22764         },
22765         [TEMPLATE_JMP] = {
22766                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22767         },
22768         [TEMPLATE_RET] = {
22769                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22770         },
22771         [TEMPLATE_INB_DX] = {
22772                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22773                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22774         },
22775         [TEMPLATE_INB_IMM] = {
22776                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22777                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22778         },
22779         [TEMPLATE_INW_DX]  = { 
22780                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22781                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22782         },
22783         [TEMPLATE_INW_IMM] = { 
22784                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22785                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22786         },
22787         [TEMPLATE_INL_DX]  = {
22788                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22789                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22790         },
22791         [TEMPLATE_INL_IMM] = {
22792                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22793                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22794         },
22795         [TEMPLATE_OUTB_DX] = { 
22796                 .rhs = {
22797                         [0] = { REG_AL,  REGCM_GPR8_LO },
22798                         [1] = { REG_DX, REGCM_GPR16 },
22799                 },
22800         },
22801         [TEMPLATE_OUTB_IMM] = { 
22802                 .rhs = {
22803                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22804                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22805                 },
22806         },
22807         [TEMPLATE_OUTW_DX] = { 
22808                 .rhs = {
22809                         [0] = { REG_AX,  REGCM_GPR16 },
22810                         [1] = { REG_DX, REGCM_GPR16 },
22811                 },
22812         },
22813         [TEMPLATE_OUTW_IMM] = {
22814                 .rhs = {
22815                         [0] = { REG_AX,  REGCM_GPR16 }, 
22816                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22817                 },
22818         },
22819         [TEMPLATE_OUTL_DX] = { 
22820                 .rhs = {
22821                         [0] = { REG_EAX, REGCM_GPR32 },
22822                         [1] = { REG_DX, REGCM_GPR16 },
22823                 },
22824         },
22825         [TEMPLATE_OUTL_IMM] = { 
22826                 .rhs = {
22827                         [0] = { REG_EAX, REGCM_GPR32 }, 
22828                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22829                 },
22830         },
22831         [TEMPLATE_BSF] = {
22832                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22833                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22834         },
22835         [TEMPLATE_RDMSR] = {
22836                 .lhs = { 
22837                         [0] = { REG_EAX, REGCM_GPR32 },
22838                         [1] = { REG_EDX, REGCM_GPR32 },
22839                 },
22840                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22841         },
22842         [TEMPLATE_WRMSR] = {
22843                 .rhs = {
22844                         [0] = { REG_ECX, REGCM_GPR32 },
22845                         [1] = { REG_EAX, REGCM_GPR32 },
22846                         [2] = { REG_EDX, REGCM_GPR32 },
22847                 },
22848         },
22849         [TEMPLATE_UMUL8] = {
22850                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22851                 .rhs = { 
22852                         [0] = { REG_AL, REGCM_GPR8_LO },
22853                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22854                 },
22855         },
22856         [TEMPLATE_UMUL16] = {
22857                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22858                 .rhs = { 
22859                         [0] = { REG_AX, REGCM_GPR16 },
22860                         [1] = { REG_UNSET, REGCM_GPR16 },
22861                 },
22862         },
22863         [TEMPLATE_UMUL32] = {
22864                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22865                 .rhs = { 
22866                         [0] = { REG_EAX, REGCM_GPR32 },
22867                         [1] = { REG_UNSET, REGCM_GPR32 },
22868                 },
22869         },
22870         [TEMPLATE_DIV8] = {
22871                 .lhs = { 
22872                         [0] = { REG_AL, REGCM_GPR8_LO },
22873                         [1] = { REG_AH, REGCM_GPR8 },
22874                 },
22875                 .rhs = {
22876                         [0] = { REG_AX, REGCM_GPR16 },
22877                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22878                 },
22879         },
22880         [TEMPLATE_DIV16] = {
22881                 .lhs = { 
22882                         [0] = { REG_AX, REGCM_GPR16 },
22883                         [1] = { REG_DX, REGCM_GPR16 },
22884                 },
22885                 .rhs = {
22886                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22887                         [1] = { REG_UNSET, REGCM_GPR16 },
22888                 },
22889         },
22890         [TEMPLATE_DIV32] = {
22891                 .lhs = { 
22892                         [0] = { REG_EAX, REGCM_GPR32 },
22893                         [1] = { REG_EDX, REGCM_GPR32 },
22894                 },
22895                 .rhs = {
22896                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22897                         [1] = { REG_UNSET, REGCM_GPR32 },
22898                 },
22899         },
22900 };
22901
22902 static void fixup_branch(struct compile_state *state,
22903         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22904         struct triple *left, struct triple *right)
22905 {
22906         struct triple *test;
22907         if (!left) {
22908                 internal_error(state, branch, "no branch test?");
22909         }
22910         test = pre_triple(state, branch,
22911                 cmp_op, cmp_type, left, right);
22912         test->template_id = TEMPLATE_TEST32; 
22913         if (cmp_op == OP_CMP) {
22914                 test->template_id = TEMPLATE_CMP32_REG;
22915                 if (get_imm32(test, &RHS(test, 1))) {
22916                         test->template_id = TEMPLATE_CMP32_IMM;
22917                 }
22918         }
22919         use_triple(RHS(test, 0), test);
22920         use_triple(RHS(test, 1), test);
22921         unuse_triple(RHS(branch, 0), branch);
22922         RHS(branch, 0) = test;
22923         branch->op = jmp_op;
22924         branch->template_id = TEMPLATE_JMP;
22925         use_triple(RHS(branch, 0), branch);
22926 }
22927
22928 static void fixup_branches(struct compile_state *state,
22929         struct triple *cmp, struct triple *use, int jmp_op)
22930 {
22931         struct triple_set *entry, *next;
22932         for(entry = use->use; entry; entry = next) {
22933                 next = entry->next;
22934                 if (entry->member->op == OP_COPY) {
22935                         fixup_branches(state, cmp, entry->member, jmp_op);
22936                 }
22937                 else if (entry->member->op == OP_CBRANCH) {
22938                         struct triple *branch;
22939                         struct triple *left, *right;
22940                         left = right = 0;
22941                         left = RHS(cmp, 0);
22942                         if (cmp->rhs > 1) {
22943                                 right = RHS(cmp, 1);
22944                         }
22945                         branch = entry->member;
22946                         fixup_branch(state, branch, jmp_op, 
22947                                 cmp->op, cmp->type, left, right);
22948                 }
22949         }
22950 }
22951
22952 static void bool_cmp(struct compile_state *state, 
22953         struct triple *ins, int cmp_op, int jmp_op, int set_op)
22954 {
22955         struct triple_set *entry, *next;
22956         struct triple *set, *convert;
22957
22958         /* Put a barrier up before the cmp which preceeds the
22959          * copy instruction.  If a set actually occurs this gives
22960          * us a chance to move variables in registers out of the way.
22961          */
22962
22963         /* Modify the comparison operator */
22964         ins->op = cmp_op;
22965         ins->template_id = TEMPLATE_TEST32;
22966         if (cmp_op == OP_CMP) {
22967                 ins->template_id = TEMPLATE_CMP32_REG;
22968                 if (get_imm32(ins, &RHS(ins, 1))) {
22969                         ins->template_id =  TEMPLATE_CMP32_IMM;
22970                 }
22971         }
22972         /* Generate the instruction sequence that will transform the
22973          * result of the comparison into a logical value.
22974          */
22975         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
22976         use_triple(ins, set);
22977         set->template_id = TEMPLATE_SET;
22978
22979         convert = set;
22980         if (!equiv_types(ins->type, set->type)) {
22981                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
22982                 use_triple(set, convert);
22983                 convert->template_id = TEMPLATE_COPY32_REG;
22984         }
22985
22986         for(entry = ins->use; entry; entry = next) {
22987                 next = entry->next;
22988                 if (entry->member == set) {
22989                         continue;
22990                 }
22991                 replace_rhs_use(state, ins, convert, entry->member);
22992         }
22993         fixup_branches(state, ins, convert, jmp_op);
22994 }
22995
22996 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
22997 {
22998         struct ins_template *template;
22999         struct reg_info result;
23000         int zlhs;
23001         if (ins->op == OP_PIECE) {
23002                 index = ins->u.cval;
23003                 ins = MISC(ins, 0);
23004         }
23005         zlhs = ins->lhs;
23006         if (triple_is_def(state, ins)) {
23007                 zlhs = 1;
23008         }
23009         if (index >= zlhs) {
23010                 internal_error(state, ins, "index %d out of range for %s",
23011                         index, tops(ins->op));
23012         }
23013         switch(ins->op) {
23014         case OP_ASM:
23015                 template = &ins->u.ainfo->tmpl;
23016                 break;
23017         default:
23018                 if (ins->template_id > LAST_TEMPLATE) {
23019                         internal_error(state, ins, "bad template number %d", 
23020                                 ins->template_id);
23021                 }
23022                 template = &templates[ins->template_id];
23023                 break;
23024         }
23025         result = template->lhs[index];
23026         result.regcm = arch_regcm_normalize(state, result.regcm);
23027         if (result.reg != REG_UNNEEDED) {
23028                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
23029         }
23030         if (result.regcm == 0) {
23031                 internal_error(state, ins, "lhs %d regcm == 0", index);
23032         }
23033         return result;
23034 }
23035
23036 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
23037 {
23038         struct reg_info result;
23039         struct ins_template *template;
23040         if ((index > ins->rhs) ||
23041                 (ins->op == OP_PIECE)) {
23042                 internal_error(state, ins, "index %d out of range for %s\n",
23043                         index, tops(ins->op));
23044         }
23045         switch(ins->op) {
23046         case OP_ASM:
23047                 template = &ins->u.ainfo->tmpl;
23048                 break;
23049         case OP_PHI:
23050                 index = 0;
23051                 /* Fall through */
23052         default:
23053                 if (ins->template_id > LAST_TEMPLATE) {
23054                         internal_error(state, ins, "bad template number %d", 
23055                                 ins->template_id);
23056                 }
23057                 template = &templates[ins->template_id];
23058                 break;
23059         }
23060         result = template->rhs[index];
23061         result.regcm = arch_regcm_normalize(state, result.regcm);
23062         if (result.regcm == 0) {
23063                 internal_error(state, ins, "rhs %d regcm == 0", index);
23064         }
23065         return result;
23066 }
23067
23068 static struct triple *mod_div(struct compile_state *state,
23069         struct triple *ins, int div_op, int index)
23070 {
23071         struct triple *div, *piece0, *piece1;
23072         
23073         /* Generate the appropriate division instruction */
23074         div = post_triple(state, ins, div_op, ins->type, 0, 0);
23075         RHS(div, 0) = RHS(ins, 0);
23076         RHS(div, 1) = RHS(ins, 1);
23077         piece0 = LHS(div, 0);
23078         piece1 = LHS(div, 1);
23079         div->template_id  = TEMPLATE_DIV32;
23080         use_triple(RHS(div, 0), div);
23081         use_triple(RHS(div, 1), div);
23082         use_triple(LHS(div, 0), div);
23083         use_triple(LHS(div, 1), div);
23084
23085         /* Replate uses of ins with the appropriate piece of the div */
23086         propogate_use(state, ins, LHS(div, index));
23087         release_triple(state, ins);
23088
23089         /* Return the address of the next instruction */
23090         return piece1->next;
23091 }
23092
23093 static int noop_adecl(struct triple *adecl)
23094 {
23095         struct triple_set *use;
23096         /* It's a noop if it doesn't specify stoorage */
23097         if (adecl->lhs == 0) {
23098                 return 1;
23099         }
23100         /* Is the adecl used? If not it's a noop */
23101         for(use = adecl->use; use ; use = use->next) {
23102                 if ((use->member->op != OP_PIECE) ||
23103                         (MISC(use->member, 0) != adecl)) {
23104                         return 0;
23105                 }
23106         }
23107         return 1;
23108 }
23109
23110 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
23111 {
23112         struct triple *mask, *nmask, *shift;
23113         struct triple *val, *val_mask, *val_shift;
23114         struct triple *targ, *targ_mask;
23115         struct triple *new;
23116         ulong_t the_mask, the_nmask;
23117
23118         targ = RHS(ins, 0);
23119         val = RHS(ins, 1);
23120
23121         /* Get constant for the mask value */
23122         the_mask = 1;
23123         the_mask <<= ins->u.bitfield.size;
23124         the_mask -= 1;
23125         the_mask <<= ins->u.bitfield.offset;
23126         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23127         mask->u.cval = the_mask;
23128
23129         /* Get the inverted mask value */
23130         the_nmask = ~the_mask;
23131         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23132         nmask->u.cval = the_nmask;
23133
23134         /* Get constant for the shift value */
23135         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23136         shift->u.cval = ins->u.bitfield.offset;
23137
23138         /* Shift and mask the source value */
23139         val_shift = val;
23140         if (shift->u.cval != 0) {
23141                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23142                 use_triple(val, val_shift);
23143                 use_triple(shift, val_shift);
23144         }
23145         val_mask = val_shift;
23146         if (is_signed(val->type)) {
23147                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23148                 use_triple(val_shift, val_mask);
23149                 use_triple(mask, val_mask);
23150         }
23151
23152         /* Mask the target value */
23153         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23154         use_triple(targ, targ_mask);
23155         use_triple(nmask, targ_mask);
23156
23157         /* Now combined them together */
23158         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23159         use_triple(targ_mask, new);
23160         use_triple(val_mask, new);
23161
23162         /* Move all of the users over to the new expression */
23163         propogate_use(state, ins, new);
23164
23165         /* Delete the original triple */
23166         release_triple(state, ins);
23167
23168         /* Restart the transformation at mask */
23169         return mask;
23170 }
23171
23172 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23173 {
23174         struct triple *mask, *shift;
23175         struct triple *val, *val_mask, *val_shift;
23176         ulong_t the_mask;
23177
23178         val = RHS(ins, 0);
23179
23180         /* Get constant for the mask value */
23181         the_mask = 1;
23182         the_mask <<= ins->u.bitfield.size;
23183         the_mask -= 1;
23184         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23185         mask->u.cval = the_mask;
23186
23187         /* Get constant for the right shift value */
23188         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23189         shift->u.cval = ins->u.bitfield.offset;
23190
23191         /* Shift arithmetic right, to correct the sign */
23192         val_shift = val;
23193         if (shift->u.cval != 0) {
23194                 int op;
23195                 if (ins->op == OP_SEXTRACT) {
23196                         op = OP_SSR;
23197                 } else {
23198                         op = OP_USR;
23199                 }
23200                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23201                 use_triple(val, val_shift);
23202                 use_triple(shift, val_shift);
23203         }
23204
23205         /* Finally mask the value */
23206         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23207         use_triple(val_shift, val_mask);
23208         use_triple(mask,      val_mask);
23209
23210         /* Move all of the users over to the new expression */
23211         propogate_use(state, ins, val_mask);
23212
23213         /* Release the original instruction */
23214         release_triple(state, ins);
23215
23216         return mask;
23217
23218 }
23219
23220 static struct triple *transform_to_arch_instruction(
23221         struct compile_state *state, struct triple *ins)
23222 {
23223         /* Transform from generic 3 address instructions
23224          * to archtecture specific instructions.
23225          * And apply architecture specific constraints to instructions.
23226          * Copies are inserted to preserve the register flexibility
23227          * of 3 address instructions.
23228          */
23229         struct triple *next, *value;
23230         size_t size;
23231         next = ins->next;
23232         switch(ins->op) {
23233         case OP_INTCONST:
23234                 ins->template_id = TEMPLATE_INTCONST32;
23235                 if (ins->u.cval < 256) {
23236                         ins->template_id = TEMPLATE_INTCONST8;
23237                 }
23238                 break;
23239         case OP_ADDRCONST:
23240                 ins->template_id = TEMPLATE_INTCONST32;
23241                 break;
23242         case OP_UNKNOWNVAL:
23243                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23244                 break;
23245         case OP_NOOP:
23246         case OP_SDECL:
23247         case OP_BLOBCONST:
23248         case OP_LABEL:
23249                 ins->template_id = TEMPLATE_NOP;
23250                 break;
23251         case OP_COPY:
23252         case OP_CONVERT:
23253                 size = size_of(state, ins->type);
23254                 value = RHS(ins, 0);
23255                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23256                         ins->template_id = TEMPLATE_COPY_IMM8;
23257                 }
23258                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23259                         ins->template_id = TEMPLATE_COPY_IMM16;
23260                 }
23261                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23262                         ins->template_id = TEMPLATE_COPY_IMM32;
23263                 }
23264                 else if (is_const(value)) {
23265                         internal_error(state, ins, "bad constant passed to copy");
23266                 }
23267                 else if (size <= SIZEOF_I8) {
23268                         ins->template_id = TEMPLATE_COPY8_REG;
23269                 }
23270                 else if (size <= SIZEOF_I16) {
23271                         ins->template_id = TEMPLATE_COPY16_REG;
23272                 }
23273                 else if (size <= SIZEOF_I32) {
23274                         ins->template_id = TEMPLATE_COPY32_REG;
23275                 }
23276                 else {
23277                         internal_error(state, ins, "bad type passed to copy");
23278                 }
23279                 break;
23280         case OP_PHI:
23281                 size = size_of(state, ins->type);
23282                 if (size <= SIZEOF_I8) {
23283                         ins->template_id = TEMPLATE_PHI8;
23284                 }
23285                 else if (size <= SIZEOF_I16) {
23286                         ins->template_id = TEMPLATE_PHI16;
23287                 }
23288                 else if (size <= SIZEOF_I32) {
23289                         ins->template_id = TEMPLATE_PHI32;
23290                 }
23291                 else {
23292                         internal_error(state, ins, "bad type passed to phi");
23293                 }
23294                 break;
23295         case OP_ADECL:
23296                 /* Adecls should always be treated as dead code and
23297                  * removed.  If we are not optimizing they may linger.
23298                  */
23299                 if (!noop_adecl(ins)) {
23300                         internal_error(state, ins, "adecl remains?");
23301                 }
23302                 ins->template_id = TEMPLATE_NOP;
23303                 next = after_lhs(state, ins);
23304                 break;
23305         case OP_STORE:
23306                 switch(ins->type->type & TYPE_MASK) {
23307                 case TYPE_CHAR:    case TYPE_UCHAR:
23308                         ins->template_id = TEMPLATE_STORE8;
23309                         break;
23310                 case TYPE_SHORT:   case TYPE_USHORT:
23311                         ins->template_id = TEMPLATE_STORE16;
23312                         break;
23313                 case TYPE_INT:     case TYPE_UINT:
23314                 case TYPE_LONG:    case TYPE_ULONG:
23315                 case TYPE_POINTER:
23316                         ins->template_id = TEMPLATE_STORE32;
23317                         break;
23318                 default:
23319                         internal_error(state, ins, "unknown type in store");
23320                         break;
23321                 }
23322                 break;
23323         case OP_LOAD:
23324                 switch(ins->type->type & TYPE_MASK) {
23325                 case TYPE_CHAR:   case TYPE_UCHAR:
23326                 case TYPE_SHORT:  case TYPE_USHORT:
23327                 case TYPE_INT:    case TYPE_UINT:
23328                 case TYPE_LONG:   case TYPE_ULONG:
23329                 case TYPE_POINTER:
23330                         break;
23331                 default:
23332                         internal_error(state, ins, "unknown type in load");
23333                         break;
23334                 }
23335                 ins->template_id = TEMPLATE_LOAD32;
23336                 break;
23337         case OP_ADD:
23338         case OP_SUB:
23339         case OP_AND:
23340         case OP_XOR:
23341         case OP_OR:
23342         case OP_SMUL:
23343                 ins->template_id = TEMPLATE_BINARY32_REG;
23344                 if (get_imm32(ins, &RHS(ins, 1))) {
23345                         ins->template_id = TEMPLATE_BINARY32_IMM;
23346                 }
23347                 break;
23348         case OP_SDIVT:
23349         case OP_UDIVT:
23350                 ins->template_id = TEMPLATE_DIV32;
23351                 next = after_lhs(state, ins);
23352                 break;
23353         case OP_UMUL:
23354                 ins->template_id = TEMPLATE_UMUL32;
23355                 break;
23356         case OP_UDIV:
23357                 next = mod_div(state, ins, OP_UDIVT, 0);
23358                 break;
23359         case OP_SDIV:
23360                 next = mod_div(state, ins, OP_SDIVT, 0);
23361                 break;
23362         case OP_UMOD:
23363                 next = mod_div(state, ins, OP_UDIVT, 1);
23364                 break;
23365         case OP_SMOD:
23366                 next = mod_div(state, ins, OP_SDIVT, 1);
23367                 break;
23368         case OP_SL:
23369         case OP_SSR:
23370         case OP_USR:
23371                 ins->template_id = TEMPLATE_SL32_CL;
23372                 if (get_imm8(ins, &RHS(ins, 1))) {
23373                         ins->template_id = TEMPLATE_SL32_IMM;
23374                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23375                         typed_pre_copy(state, &uchar_type, ins, 1);
23376                 }
23377                 break;
23378         case OP_INVERT:
23379         case OP_NEG:
23380                 ins->template_id = TEMPLATE_UNARY32;
23381                 break;
23382         case OP_EQ: 
23383                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23384                 break;
23385         case OP_NOTEQ:
23386                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23387                 break;
23388         case OP_SLESS:
23389                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23390                 break;
23391         case OP_ULESS:
23392                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23393                 break;
23394         case OP_SMORE:
23395                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23396                 break;
23397         case OP_UMORE:
23398                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23399                 break;
23400         case OP_SLESSEQ:
23401                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23402                 break;
23403         case OP_ULESSEQ:
23404                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23405                 break;
23406         case OP_SMOREEQ:
23407                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23408                 break;
23409         case OP_UMOREEQ:
23410                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23411                 break;
23412         case OP_LTRUE:
23413                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23414                 break;
23415         case OP_LFALSE:
23416                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23417                 break;
23418         case OP_BRANCH:
23419                 ins->op = OP_JMP;
23420                 ins->template_id = TEMPLATE_NOP;
23421                 break;
23422         case OP_CBRANCH:
23423                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23424                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23425                 break;
23426         case OP_CALL:
23427                 ins->template_id = TEMPLATE_NOP;
23428                 break;
23429         case OP_RET:
23430                 ins->template_id = TEMPLATE_RET;
23431                 break;
23432         case OP_INB:
23433         case OP_INW:
23434         case OP_INL:
23435                 switch(ins->op) {
23436                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23437                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23438                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23439                 }
23440                 if (get_imm8(ins, &RHS(ins, 0))) {
23441                         ins->template_id += 1;
23442                 }
23443                 break;
23444         case OP_OUTB:
23445         case OP_OUTW:
23446         case OP_OUTL:
23447                 switch(ins->op) {
23448                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23449                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23450                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23451                 }
23452                 if (get_imm8(ins, &RHS(ins, 1))) {
23453                         ins->template_id += 1;
23454                 }
23455                 break;
23456         case OP_BSF:
23457         case OP_BSR:
23458                 ins->template_id = TEMPLATE_BSF;
23459                 break;
23460         case OP_RDMSR:
23461                 ins->template_id = TEMPLATE_RDMSR;
23462                 next = after_lhs(state, ins);
23463                 break;
23464         case OP_WRMSR:
23465                 ins->template_id = TEMPLATE_WRMSR;
23466                 break;
23467         case OP_HLT:
23468                 ins->template_id = TEMPLATE_NOP;
23469                 break;
23470         case OP_ASM:
23471                 ins->template_id = TEMPLATE_NOP;
23472                 next = after_lhs(state, ins);
23473                 break;
23474                 /* Already transformed instructions */
23475         case OP_TEST:
23476                 ins->template_id = TEMPLATE_TEST32;
23477                 break;
23478         case OP_CMP:
23479                 ins->template_id = TEMPLATE_CMP32_REG;
23480                 if (get_imm32(ins, &RHS(ins, 1))) {
23481                         ins->template_id = TEMPLATE_CMP32_IMM;
23482                 }
23483                 break;
23484         case OP_JMP:
23485                 ins->template_id = TEMPLATE_NOP;
23486                 break;
23487         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23488         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23489         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23490         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23491         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23492                 ins->template_id = TEMPLATE_JMP;
23493                 break;
23494         case OP_SET_EQ:      case OP_SET_NOTEQ:
23495         case OP_SET_SLESS:   case OP_SET_ULESS:
23496         case OP_SET_SMORE:   case OP_SET_UMORE:
23497         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23498         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23499                 ins->template_id = TEMPLATE_SET;
23500                 break;
23501         case OP_DEPOSIT:
23502                 next = x86_deposit(state, ins);
23503                 break;
23504         case OP_SEXTRACT:
23505         case OP_UEXTRACT:
23506                 next = x86_extract(state, ins);
23507                 break;
23508                 /* Unhandled instructions */
23509         case OP_PIECE:
23510         default:
23511                 internal_error(state, ins, "unhandled ins: %d %s",
23512                         ins->op, tops(ins->op));
23513                 break;
23514         }
23515         return next;
23516 }
23517
23518 static long next_label(struct compile_state *state)
23519 {
23520         static long label_counter = 1000;
23521         return ++label_counter;
23522 }
23523 static void generate_local_labels(struct compile_state *state)
23524 {
23525         struct triple *first, *label;
23526         first = state->first;
23527         label = first;
23528         do {
23529                 if ((label->op == OP_LABEL) || 
23530                         (label->op == OP_SDECL)) {
23531                         if (label->use) {
23532                                 label->u.cval = next_label(state);
23533                         } else {
23534                                 label->u.cval = 0;
23535                         }
23536                         
23537                 }
23538                 label = label->next;
23539         } while(label != first);
23540 }
23541
23542 static int check_reg(struct compile_state *state, 
23543         struct triple *triple, int classes)
23544 {
23545         unsigned mask;
23546         int reg;
23547         reg = ID_REG(triple->id);
23548         if (reg == REG_UNSET) {
23549                 internal_error(state, triple, "register not set");
23550         }
23551         mask = arch_reg_regcm(state, reg);
23552         if (!(classes & mask)) {
23553                 internal_error(state, triple, "reg %d in wrong class",
23554                         reg);
23555         }
23556         return reg;
23557 }
23558
23559
23560 #if REG_XMM7 != 44
23561 #error "Registers have renumberd fix arch_reg_str"
23562 #endif
23563 static const char *arch_regs[] = {
23564         "%unset",
23565         "%unneeded",
23566         "%eflags",
23567         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23568         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23569         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23570         "%edx:%eax",
23571         "%dx:%ax",
23572         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23573         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23574         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23575 };
23576 static const char *arch_reg_str(int reg)
23577 {
23578         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23579                 reg = 0;
23580         }
23581         return arch_regs[reg];
23582 }
23583
23584 static const char *reg(struct compile_state *state, struct triple *triple,
23585         int classes)
23586 {
23587         int reg;
23588         reg = check_reg(state, triple, classes);
23589         return arch_reg_str(reg);
23590 }
23591
23592 static int arch_reg_size(int reg)
23593 {
23594         int size;
23595         size = 0;
23596         if (reg == REG_EFLAGS) {
23597                 size = 32;
23598         }
23599         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23600                 size = 8;
23601         }
23602         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23603                 size = 16;
23604         }
23605         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23606                 size = 32;
23607         }
23608         else if (reg == REG_EDXEAX) {
23609                 size = 64;
23610         }
23611         else if (reg == REG_DXAX) {
23612                 size = 32;
23613         }
23614         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23615                 size = 64;
23616         }
23617         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23618                 size = 128;
23619         }
23620         return size;
23621 }
23622
23623 static int reg_size(struct compile_state *state, struct triple *ins)
23624 {
23625         int reg;
23626         reg = ID_REG(ins->id);
23627         if (reg == REG_UNSET) {
23628                 internal_error(state, ins, "register not set");
23629         }
23630         return arch_reg_size(reg);
23631 }
23632         
23633
23634
23635 const char *type_suffix(struct compile_state *state, struct type *type)
23636 {
23637         const char *suffix;
23638         switch(size_of(state, type)) {
23639         case SIZEOF_I8:  suffix = "b"; break;
23640         case SIZEOF_I16: suffix = "w"; break;
23641         case SIZEOF_I32: suffix = "l"; break;
23642         default:
23643                 internal_error(state, 0, "unknown suffix");
23644                 suffix = 0;
23645                 break;
23646         }
23647         return suffix;
23648 }
23649
23650 static void print_const_val(
23651         struct compile_state *state, struct triple *ins, FILE *fp)
23652 {
23653         switch(ins->op) {
23654         case OP_INTCONST:
23655                 fprintf(fp, " $%ld ", 
23656                         (long)(ins->u.cval));
23657                 break;
23658         case OP_ADDRCONST:
23659                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23660                         (MISC(ins, 0)->op != OP_LABEL))
23661                 {
23662                         internal_error(state, ins, "bad base for addrconst");
23663                 }
23664                 if (MISC(ins, 0)->u.cval <= 0) {
23665                         internal_error(state, ins, "unlabeled constant");
23666                 }
23667                 fprintf(fp, " $L%s%lu+%lu ",
23668                         state->compiler->label_prefix, 
23669                         (unsigned long)(MISC(ins, 0)->u.cval),
23670                         (unsigned long)(ins->u.cval));
23671                 break;
23672         default:
23673                 internal_error(state, ins, "unknown constant type");
23674                 break;
23675         }
23676 }
23677
23678 static void print_const(struct compile_state *state,
23679         struct triple *ins, FILE *fp)
23680 {
23681         switch(ins->op) {
23682         case OP_INTCONST:
23683                 switch(ins->type->type & TYPE_MASK) {
23684                 case TYPE_CHAR:
23685                 case TYPE_UCHAR:
23686                         fprintf(fp, ".byte 0x%02lx\n", 
23687                                 (unsigned long)(ins->u.cval));
23688                         break;
23689                 case TYPE_SHORT:
23690                 case TYPE_USHORT:
23691                         fprintf(fp, ".short 0x%04lx\n", 
23692                                 (unsigned long)(ins->u.cval));
23693                         break;
23694                 case TYPE_INT:
23695                 case TYPE_UINT:
23696                 case TYPE_LONG:
23697                 case TYPE_ULONG:
23698                 case TYPE_POINTER:
23699                         fprintf(fp, ".int %lu\n", 
23700                                 (unsigned long)(ins->u.cval));
23701                         break;
23702                 default:
23703                         fprintf(state->errout, "type: ");
23704                         name_of(state->errout, ins->type);
23705                         fprintf(state->errout, "\n");
23706                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23707                                 (unsigned long)(ins->u.cval));
23708                 }
23709                 
23710                 break;
23711         case OP_ADDRCONST:
23712                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23713                         (MISC(ins, 0)->op != OP_LABEL)) {
23714                         internal_error(state, ins, "bad base for addrconst");
23715                 }
23716                 if (MISC(ins, 0)->u.cval <= 0) {
23717                         internal_error(state, ins, "unlabeled constant");
23718                 }
23719                 fprintf(fp, ".int L%s%lu+%lu\n",
23720                         state->compiler->label_prefix,
23721                         (unsigned long)(MISC(ins, 0)->u.cval),
23722                         (unsigned long)(ins->u.cval));
23723                 break;
23724         case OP_BLOBCONST:
23725         {
23726                 unsigned char *blob;
23727                 size_t size, i;
23728                 size = size_of_in_bytes(state, ins->type);
23729                 blob = ins->u.blob;
23730                 for(i = 0; i < size; i++) {
23731                         fprintf(fp, ".byte 0x%02x\n",
23732                                 blob[i]);
23733                 }
23734                 break;
23735         }
23736         default:
23737                 internal_error(state, ins, "Unknown constant type");
23738                 break;
23739         }
23740 }
23741
23742 #define TEXT_SECTION ".rom.text"
23743 #define DATA_SECTION ".rom.data"
23744
23745 static long get_const_pool_ref(
23746         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23747 {
23748         size_t fill_bytes;
23749         long ref;
23750         ref = next_label(state);
23751         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23752         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
23753         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23754         print_const(state, ins, fp);
23755         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23756         if (fill_bytes) {
23757                 fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
23758         }
23759         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23760         return ref;
23761 }
23762
23763 static long get_mask_pool_ref(
23764         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23765 {
23766         long ref;
23767         if (mask == 0xff) {
23768                 ref = 1;
23769         }
23770         else if (mask == 0xffff) {
23771                 ref = 2;
23772         }
23773         else {
23774                 ref = 0;
23775                 internal_error(state, ins, "unhandled mask value");
23776         }
23777         return ref;
23778 }
23779
23780 static void print_binary_op(struct compile_state *state,
23781         const char *op, struct triple *ins, FILE *fp) 
23782 {
23783         unsigned mask;
23784         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23785         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23786                 internal_error(state, ins, "invalid register assignment");
23787         }
23788         if (is_const(RHS(ins, 1))) {
23789                 fprintf(fp, "\t%s ", op);
23790                 print_const_val(state, RHS(ins, 1), fp);
23791                 fprintf(fp, ", %s\n",
23792                         reg(state, RHS(ins, 0), mask));
23793         }
23794         else {
23795                 unsigned lmask, rmask;
23796                 int lreg, rreg;
23797                 lreg = check_reg(state, RHS(ins, 0), mask);
23798                 rreg = check_reg(state, RHS(ins, 1), mask);
23799                 lmask = arch_reg_regcm(state, lreg);
23800                 rmask = arch_reg_regcm(state, rreg);
23801                 mask = lmask & rmask;
23802                 fprintf(fp, "\t%s %s, %s\n",
23803                         op,
23804                         reg(state, RHS(ins, 1), mask),
23805                         reg(state, RHS(ins, 0), mask));
23806         }
23807 }
23808 static void print_unary_op(struct compile_state *state, 
23809         const char *op, struct triple *ins, FILE *fp)
23810 {
23811         unsigned mask;
23812         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23813         fprintf(fp, "\t%s %s\n",
23814                 op,
23815                 reg(state, RHS(ins, 0), mask));
23816 }
23817
23818 static void print_op_shift(struct compile_state *state,
23819         const char *op, struct triple *ins, FILE *fp)
23820 {
23821         unsigned mask;
23822         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23823         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23824                 internal_error(state, ins, "invalid register assignment");
23825         }
23826         if (is_const(RHS(ins, 1))) {
23827                 fprintf(fp, "\t%s ", op);
23828                 print_const_val(state, RHS(ins, 1), fp);
23829                 fprintf(fp, ", %s\n",
23830                         reg(state, RHS(ins, 0), mask));
23831         }
23832         else {
23833                 fprintf(fp, "\t%s %s, %s\n",
23834                         op,
23835                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23836                         reg(state, RHS(ins, 0), mask));
23837         }
23838 }
23839
23840 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23841 {
23842         const char *op;
23843         int mask;
23844         int dreg;
23845         mask = 0;
23846         switch(ins->op) {
23847         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23848         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23849         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23850         default:
23851                 internal_error(state, ins, "not an in operation");
23852                 op = 0;
23853                 break;
23854         }
23855         dreg = check_reg(state, ins, mask);
23856         if (!reg_is_reg(state, dreg, REG_EAX)) {
23857                 internal_error(state, ins, "dst != %%eax");
23858         }
23859         if (is_const(RHS(ins, 0))) {
23860                 fprintf(fp, "\t%s ", op);
23861                 print_const_val(state, RHS(ins, 0), fp);
23862                 fprintf(fp, ", %s\n",
23863                         reg(state, ins, mask));
23864         }
23865         else {
23866                 int addr_reg;
23867                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23868                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23869                         internal_error(state, ins, "src != %%dx");
23870                 }
23871                 fprintf(fp, "\t%s %s, %s\n",
23872                         op, 
23873                         reg(state, RHS(ins, 0), REGCM_GPR16),
23874                         reg(state, ins, mask));
23875         }
23876 }
23877
23878 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23879 {
23880         const char *op;
23881         int mask;
23882         int lreg;
23883         mask = 0;
23884         switch(ins->op) {
23885         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23886         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23887         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23888         default:
23889                 internal_error(state, ins, "not an out operation");
23890                 op = 0;
23891                 break;
23892         }
23893         lreg = check_reg(state, RHS(ins, 0), mask);
23894         if (!reg_is_reg(state, lreg, REG_EAX)) {
23895                 internal_error(state, ins, "src != %%eax");
23896         }
23897         if (is_const(RHS(ins, 1))) {
23898                 fprintf(fp, "\t%s %s,", 
23899                         op, reg(state, RHS(ins, 0), mask));
23900                 print_const_val(state, RHS(ins, 1), fp);
23901                 fprintf(fp, "\n");
23902         }
23903         else {
23904                 int addr_reg;
23905                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23906                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23907                         internal_error(state, ins, "dst != %%dx");
23908                 }
23909                 fprintf(fp, "\t%s %s, %s\n",
23910                         op, 
23911                         reg(state, RHS(ins, 0), mask),
23912                         reg(state, RHS(ins, 1), REGCM_GPR16));
23913         }
23914 }
23915
23916 static void print_op_move(struct compile_state *state,
23917         struct triple *ins, FILE *fp)
23918 {
23919         /* op_move is complex because there are many types
23920          * of registers we can move between.
23921          * Because OP_COPY will be introduced in arbitrary locations
23922          * OP_COPY must not affect flags.
23923          * OP_CONVERT can change the flags and it is the only operation
23924          * where it is expected the types in the registers can change.
23925          */
23926         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
23927         struct triple *dst, *src;
23928         if (state->arch->features & X86_NOOP_COPY) {
23929                 omit_copy = 0;
23930         }
23931         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
23932                 src = RHS(ins, 0);
23933                 dst = ins;
23934         }
23935         else {
23936                 internal_error(state, ins, "unknown move operation");
23937                 src = dst = 0;
23938         }
23939         if (reg_size(state, dst) < size_of(state, dst->type)) {
23940                 internal_error(state, ins, "Invalid destination register");
23941         }
23942         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
23943                 fprintf(state->errout, "src type: ");
23944                 name_of(state->errout, src->type);
23945                 fprintf(state->errout, "\n");
23946                 fprintf(state->errout, "dst type: ");
23947                 name_of(state->errout, dst->type);
23948                 fprintf(state->errout, "\n");
23949                 internal_error(state, ins, "Type mismatch for OP_COPY");
23950         }
23951
23952         if (!is_const(src)) {
23953                 int src_reg, dst_reg;
23954                 int src_regcm, dst_regcm;
23955                 src_reg   = ID_REG(src->id);
23956                 dst_reg   = ID_REG(dst->id);
23957                 src_regcm = arch_reg_regcm(state, src_reg);
23958                 dst_regcm = arch_reg_regcm(state, dst_reg);
23959                 /* If the class is the same just move the register */
23960                 if (src_regcm & dst_regcm & 
23961                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
23962                         if ((src_reg != dst_reg) || !omit_copy) {
23963                                 fprintf(fp, "\tmov %s, %s\n",
23964                                         reg(state, src, src_regcm),
23965                                         reg(state, dst, dst_regcm));
23966                         }
23967                 }
23968                 /* Move 32bit to 16bit */
23969                 else if ((src_regcm & REGCM_GPR32) &&
23970                         (dst_regcm & REGCM_GPR16)) {
23971                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
23972                         if ((src_reg != dst_reg) || !omit_copy) {
23973                                 fprintf(fp, "\tmovw %s, %s\n",
23974                                         arch_reg_str(src_reg), 
23975                                         arch_reg_str(dst_reg));
23976                         }
23977                 }
23978                 /* Move from 32bit gprs to 16bit gprs */
23979                 else if ((src_regcm & REGCM_GPR32) &&
23980                         (dst_regcm & REGCM_GPR16)) {
23981                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23982                         if ((src_reg != dst_reg) || !omit_copy) {
23983                                 fprintf(fp, "\tmov %s, %s\n",
23984                                         arch_reg_str(src_reg),
23985                                         arch_reg_str(dst_reg));
23986                         }
23987                 }
23988                 /* Move 32bit to 8bit */
23989                 else if ((src_regcm & REGCM_GPR32_8) &&
23990                         (dst_regcm & REGCM_GPR8_LO))
23991                 {
23992                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
23993                         if ((src_reg != dst_reg) || !omit_copy) {
23994                                 fprintf(fp, "\tmovb %s, %s\n",
23995                                         arch_reg_str(src_reg),
23996                                         arch_reg_str(dst_reg));
23997                         }
23998                 }
23999                 /* Move 16bit to 8bit */
24000                 else if ((src_regcm & REGCM_GPR16_8) &&
24001                         (dst_regcm & REGCM_GPR8_LO))
24002                 {
24003                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
24004                         if ((src_reg != dst_reg) || !omit_copy) {
24005                                 fprintf(fp, "\tmovb %s, %s\n",
24006                                         arch_reg_str(src_reg),
24007                                         arch_reg_str(dst_reg));
24008                         }
24009                 }
24010                 /* Move 8/16bit to 16/32bit */
24011                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
24012                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
24013                         const char *op;
24014                         op = is_signed(src->type)? "movsx": "movzx";
24015                         fprintf(fp, "\t%s %s, %s\n",
24016                                 op,
24017                                 reg(state, src, src_regcm),
24018                                 reg(state, dst, dst_regcm));
24019                 }
24020                 /* Move between sse registers */
24021                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
24022                         if ((src_reg != dst_reg) || !omit_copy) {
24023                                 fprintf(fp, "\tmovdqa %s, %s\n",
24024                                         reg(state, src, src_regcm),
24025                                         reg(state, dst, dst_regcm));
24026                         }
24027                 }
24028                 /* Move between mmx registers */
24029                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
24030                         if ((src_reg != dst_reg) || !omit_copy) {
24031                                 fprintf(fp, "\tmovq %s, %s\n",
24032                                         reg(state, src, src_regcm),
24033                                         reg(state, dst, dst_regcm));
24034                         }
24035                 }
24036                 /* Move from sse to mmx registers */
24037                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
24038                         fprintf(fp, "\tmovdq2q %s, %s\n",
24039                                 reg(state, src, src_regcm),
24040                                 reg(state, dst, dst_regcm));
24041                 }
24042                 /* Move from mmx to sse registers */
24043                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
24044                         fprintf(fp, "\tmovq2dq %s, %s\n",
24045                                 reg(state, src, src_regcm),
24046                                 reg(state, dst, dst_regcm));
24047                 }
24048                 /* Move between 32bit gprs & mmx/sse registers */
24049                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
24050                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
24051                         fprintf(fp, "\tmovd %s, %s\n",
24052                                 reg(state, src, src_regcm),
24053                                 reg(state, dst, dst_regcm));
24054                 }
24055                 /* Move from 16bit gprs &  mmx/sse registers */
24056                 else if ((src_regcm & REGCM_GPR16) &&
24057                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24058                         const char *op;
24059                         int mid_reg;
24060                         op = is_signed(src->type)? "movsx":"movzx";
24061                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24062                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24063                                 op,
24064                                 arch_reg_str(src_reg),
24065                                 arch_reg_str(mid_reg),
24066                                 arch_reg_str(mid_reg),
24067                                 arch_reg_str(dst_reg));
24068                 }
24069                 /* Move from mmx/sse registers to 16bit gprs */
24070                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24071                         (dst_regcm & REGCM_GPR16)) {
24072                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24073                         fprintf(fp, "\tmovd %s, %s\n",
24074                                 arch_reg_str(src_reg),
24075                                 arch_reg_str(dst_reg));
24076                 }
24077                 /* Move from gpr to 64bit dividend */
24078                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
24079                         (dst_regcm & REGCM_DIVIDEND64)) {
24080                         const char *extend;
24081                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
24082                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
24083                                 arch_reg_str(src_reg), 
24084                                 extend);
24085                 }
24086                 /* Move from 64bit gpr to gpr */
24087                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24088                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
24089                         if (dst_regcm & REGCM_GPR32) {
24090                                 src_reg = REG_EAX;
24091                         } 
24092                         else if (dst_regcm & REGCM_GPR16) {
24093                                 src_reg = REG_AX;
24094                         }
24095                         else if (dst_regcm & REGCM_GPR8_LO) {
24096                                 src_reg = REG_AL;
24097                         }
24098                         fprintf(fp, "\tmov %s, %s\n",
24099                                 arch_reg_str(src_reg),
24100                                 arch_reg_str(dst_reg));
24101                 }
24102                 /* Move from mmx/sse registers to 64bit gpr */
24103                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24104                         (dst_regcm & REGCM_DIVIDEND64)) {
24105                         const char *extend;
24106                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
24107                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
24108                                 arch_reg_str(src_reg),
24109                                 extend);
24110                 }
24111                 /* Move from 64bit gpr to mmx/sse register */
24112                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24113                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
24114                         fprintf(fp, "\tmovd %%eax, %s\n",
24115                                 arch_reg_str(dst_reg));
24116                 }
24117 #if X86_4_8BIT_GPRS
24118                 /* Move from 8bit gprs to  mmx/sse registers */
24119                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
24120                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24121                         const char *op;
24122                         int mid_reg;
24123                         op = is_signed(src->type)? "movsx":"movzx";
24124                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24125                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24126                                 op,
24127                                 reg(state, src, src_regcm),
24128                                 arch_reg_str(mid_reg),
24129                                 arch_reg_str(mid_reg),
24130                                 reg(state, dst, dst_regcm));
24131                 }
24132                 /* Move from mmx/sse registers and 8bit gprs */
24133                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24134                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
24135                         int mid_reg;
24136                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24137                         fprintf(fp, "\tmovd %s, %s\n",
24138                                 reg(state, src, src_regcm),
24139                                 arch_reg_str(mid_reg));
24140                 }
24141                 /* Move from 32bit gprs to 8bit gprs */
24142                 else if ((src_regcm & REGCM_GPR32) &&
24143                         (dst_regcm & REGCM_GPR8_LO)) {
24144                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24145                         if ((src_reg != dst_reg) || !omit_copy) {
24146                                 fprintf(fp, "\tmov %s, %s\n",
24147                                         arch_reg_str(src_reg),
24148                                         arch_reg_str(dst_reg));
24149                         }
24150                 }
24151                 /* Move from 16bit gprs to 8bit gprs */
24152                 else if ((src_regcm & REGCM_GPR16) &&
24153                         (dst_regcm & REGCM_GPR8_LO)) {
24154                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24155                         if ((src_reg != dst_reg) || !omit_copy) {
24156                                 fprintf(fp, "\tmov %s, %s\n",
24157                                         arch_reg_str(src_reg),
24158                                         arch_reg_str(dst_reg));
24159                         }
24160                 }
24161 #endif /* X86_4_8BIT_GPRS */
24162                 /* Move from %eax:%edx to %eax:%edx */
24163                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24164                         (dst_regcm & REGCM_DIVIDEND64) &&
24165                         (src_reg == dst_reg)) {
24166                         if (!omit_copy) {
24167                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24168                                         arch_reg_str(src_reg),
24169                                         arch_reg_str(dst_reg));
24170                         }
24171                 }
24172                 else {
24173                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24174                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24175                         }
24176                         internal_error(state, ins, "unknown copy type");
24177                 }
24178         }
24179         else {
24180                 size_t dst_size;
24181                 int dst_reg;
24182                 int dst_regcm;
24183                 dst_size = size_of(state, dst->type);
24184                 dst_reg = ID_REG(dst->id);
24185                 dst_regcm = arch_reg_regcm(state, dst_reg);
24186                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24187                         fprintf(fp, "\tmov ");
24188                         print_const_val(state, src, fp);
24189                         fprintf(fp, ", %s\n",
24190                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24191                 }
24192                 else if (dst_regcm & REGCM_DIVIDEND64) {
24193                         if (dst_size > SIZEOF_I32) {
24194                                 internal_error(state, ins, "%dbit constant...", dst_size);
24195                         }
24196                         fprintf(fp, "\tmov $0, %%edx\n");
24197                         fprintf(fp, "\tmov ");
24198                         print_const_val(state, src, fp);
24199                         fprintf(fp, ", %%eax\n");
24200                 }
24201                 else if (dst_regcm & REGCM_DIVIDEND32) {
24202                         if (dst_size > SIZEOF_I16) {
24203                                 internal_error(state, ins, "%dbit constant...", dst_size);
24204                         }
24205                         fprintf(fp, "\tmov $0, %%dx\n");
24206                         fprintf(fp, "\tmov ");
24207                         print_const_val(state, src, fp);
24208                         fprintf(fp, ", %%ax");
24209                 }
24210                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24211                         long ref;
24212                         if (dst_size > SIZEOF_I32) {
24213                                 internal_error(state, ins, "%d bit constant...", dst_size);
24214                         }
24215                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24216                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24217                                 state->compiler->label_prefix, ref,
24218                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24219                 }
24220                 else {
24221                         internal_error(state, ins, "unknown copy immediate type");
24222                 }
24223         }
24224         /* Leave now if this is not a type conversion */
24225         if (ins->op != OP_CONVERT) {
24226                 return;
24227         }
24228         /* Now make certain I have not logically overflowed the destination */
24229         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24230                 (size_of(state, dst->type) < reg_size(state, dst)))
24231         {
24232                 unsigned long mask;
24233                 int dst_reg;
24234                 int dst_regcm;
24235                 if (size_of(state, dst->type) >= 32) {
24236                         fprintf(state->errout, "dst type: ");
24237                         name_of(state->errout, dst->type);
24238                         fprintf(state->errout, "\n");
24239                         internal_error(state, dst, "unhandled dst type size");
24240                 }
24241                 mask = 1;
24242                 mask <<= size_of(state, dst->type);
24243                 mask -= 1;
24244
24245                 dst_reg = ID_REG(dst->id);
24246                 dst_regcm = arch_reg_regcm(state, dst_reg);
24247
24248                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24249                         fprintf(fp, "\tand $0x%lx, %s\n",
24250                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24251                 }
24252                 else if (dst_regcm & REGCM_MMX) {
24253                         long ref;
24254                         ref = get_mask_pool_ref(state, dst, mask, fp);
24255                         fprintf(fp, "\tpand L%s%lu, %s\n",
24256                                 state->compiler->label_prefix, ref,
24257                                 reg(state, dst, REGCM_MMX));
24258                 }
24259                 else if (dst_regcm & REGCM_XMM) {
24260                         long ref;
24261                         ref = get_mask_pool_ref(state, dst, mask, fp);
24262                         fprintf(fp, "\tpand L%s%lu, %s\n",
24263                                 state->compiler->label_prefix, ref,
24264                                 reg(state, dst, REGCM_XMM));
24265                 }
24266                 else {
24267                         fprintf(state->errout, "dst type: ");
24268                         name_of(state->errout, dst->type);
24269                         fprintf(state->errout, "\n");
24270                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24271                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24272                 }
24273         }
24274         /* Make certain I am properly sign extended */
24275         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24276                 (is_signed(src->type)))
24277         {
24278                 int bits, reg_bits, shift_bits;
24279                 int dst_reg;
24280                 int dst_regcm;
24281
24282                 bits = size_of(state, src->type);
24283                 reg_bits = reg_size(state, dst);
24284                 if (reg_bits > 32) {
24285                         reg_bits = 32;
24286                 }
24287                 shift_bits = reg_bits - size_of(state, src->type);
24288                 dst_reg = ID_REG(dst->id);
24289                 dst_regcm = arch_reg_regcm(state, dst_reg);
24290
24291                 if (shift_bits < 0) {
24292                         internal_error(state, dst, "negative shift?");
24293                 }
24294
24295                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24296                         fprintf(fp, "\tshl $%d, %s\n", 
24297                                 shift_bits, 
24298                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24299                         fprintf(fp, "\tsar $%d, %s\n", 
24300                                 shift_bits, 
24301                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24302                 }
24303                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24304                         fprintf(fp, "\tpslld $%d, %s\n",
24305                                 shift_bits, 
24306                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24307                         fprintf(fp, "\tpsrad $%d, %s\n",
24308                                 shift_bits, 
24309                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24310                 }
24311                 else {
24312                         fprintf(state->errout, "dst type: ");
24313                         name_of(state->errout, dst->type);
24314                         fprintf(state->errout, "\n");
24315                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24316                         internal_error(state, dst, "failed to signed extend value");
24317                 }
24318         }
24319 }
24320
24321 static void print_op_load(struct compile_state *state,
24322         struct triple *ins, FILE *fp)
24323 {
24324         struct triple *dst, *src;
24325         const char *op;
24326         dst = ins;
24327         src = RHS(ins, 0);
24328         if (is_const(src) || is_const(dst)) {
24329                 internal_error(state, ins, "unknown load operation");
24330         }
24331         switch(ins->type->type & TYPE_MASK) {
24332         case TYPE_CHAR:   op = "movsbl"; break;
24333         case TYPE_UCHAR:  op = "movzbl"; break;
24334         case TYPE_SHORT:  op = "movswl"; break;
24335         case TYPE_USHORT: op = "movzwl"; break;
24336         case TYPE_INT:    case TYPE_UINT:
24337         case TYPE_LONG:   case TYPE_ULONG:
24338         case TYPE_POINTER:
24339                 op = "movl"; 
24340                 break;
24341         default:
24342                 internal_error(state, ins, "unknown type in load");
24343                 op = "<invalid opcode>";
24344                 break;
24345         }
24346         fprintf(fp, "\t%s (%s), %s\n",
24347                 op, 
24348                 reg(state, src, REGCM_GPR32),
24349                 reg(state, dst, REGCM_GPR32));
24350 }
24351
24352
24353 static void print_op_store(struct compile_state *state,
24354         struct triple *ins, FILE *fp)
24355 {
24356         struct triple *dst, *src;
24357         dst = RHS(ins, 0);
24358         src = RHS(ins, 1);
24359         if (is_const(src) && (src->op == OP_INTCONST)) {
24360                 long_t value;
24361                 value = (long_t)(src->u.cval);
24362                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24363                         type_suffix(state, src->type),
24364                         (long)(value),
24365                         reg(state, dst, REGCM_GPR32));
24366         }
24367         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24368                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24369                         type_suffix(state, src->type),
24370                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24371                         (unsigned long)(dst->u.cval));
24372         }
24373         else {
24374                 if (is_const(src) || is_const(dst)) {
24375                         internal_error(state, ins, "unknown store operation");
24376                 }
24377                 fprintf(fp, "\tmov%s %s, (%s)\n",
24378                         type_suffix(state, src->type),
24379                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24380                         reg(state, dst, REGCM_GPR32));
24381         }
24382         
24383         
24384 }
24385
24386 static void print_op_smul(struct compile_state *state,
24387         struct triple *ins, FILE *fp)
24388 {
24389         if (!is_const(RHS(ins, 1))) {
24390                 fprintf(fp, "\timul %s, %s\n",
24391                         reg(state, RHS(ins, 1), REGCM_GPR32),
24392                         reg(state, RHS(ins, 0), REGCM_GPR32));
24393         }
24394         else {
24395                 fprintf(fp, "\timul ");
24396                 print_const_val(state, RHS(ins, 1), fp);
24397                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24398         }
24399 }
24400
24401 static void print_op_cmp(struct compile_state *state,
24402         struct triple *ins, FILE *fp)
24403 {
24404         unsigned mask;
24405         int dreg;
24406         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24407         dreg = check_reg(state, ins, REGCM_FLAGS);
24408         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24409                 internal_error(state, ins, "bad dest register for cmp");
24410         }
24411         if (is_const(RHS(ins, 1))) {
24412                 fprintf(fp, "\tcmp ");
24413                 print_const_val(state, RHS(ins, 1), fp);
24414                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24415         }
24416         else {
24417                 unsigned lmask, rmask;
24418                 int lreg, rreg;
24419                 lreg = check_reg(state, RHS(ins, 0), mask);
24420                 rreg = check_reg(state, RHS(ins, 1), mask);
24421                 lmask = arch_reg_regcm(state, lreg);
24422                 rmask = arch_reg_regcm(state, rreg);
24423                 mask = lmask & rmask;
24424                 fprintf(fp, "\tcmp %s, %s\n",
24425                         reg(state, RHS(ins, 1), mask),
24426                         reg(state, RHS(ins, 0), mask));
24427         }
24428 }
24429
24430 static void print_op_test(struct compile_state *state,
24431         struct triple *ins, FILE *fp)
24432 {
24433         unsigned mask;
24434         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24435         fprintf(fp, "\ttest %s, %s\n",
24436                 reg(state, RHS(ins, 0), mask),
24437                 reg(state, RHS(ins, 0), mask));
24438 }
24439
24440 static void print_op_branch(struct compile_state *state,
24441         struct triple *branch, FILE *fp)
24442 {
24443         const char *bop = "j";
24444         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24445                 if (branch->rhs != 0) {
24446                         internal_error(state, branch, "jmp with condition?");
24447                 }
24448                 bop = "jmp";
24449         }
24450         else {
24451                 struct triple *ptr;
24452                 if (branch->rhs != 1) {
24453                         internal_error(state, branch, "jmpcc without condition?");
24454                 }
24455                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24456                 if ((RHS(branch, 0)->op != OP_CMP) &&
24457                         (RHS(branch, 0)->op != OP_TEST)) {
24458                         internal_error(state, branch, "bad branch test");
24459                 }
24460 #warning "FIXME I have observed instructions between the test and branch instructions"
24461                 ptr = RHS(branch, 0);
24462                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24463                         if (ptr->op != OP_COPY) {
24464                                 internal_error(state, branch, "branch does not follow test");
24465                         }
24466                 }
24467                 switch(branch->op) {
24468                 case OP_JMP_EQ:       bop = "jz";  break;
24469                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24470                 case OP_JMP_SLESS:    bop = "jl";  break;
24471                 case OP_JMP_ULESS:    bop = "jb";  break;
24472                 case OP_JMP_SMORE:    bop = "jg";  break;
24473                 case OP_JMP_UMORE:    bop = "ja";  break;
24474                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24475                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24476                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24477                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24478                 default:
24479                         internal_error(state, branch, "Invalid branch op");
24480                         break;
24481                 }
24482                 
24483         }
24484 #if 1
24485         if (branch->op == OP_CALL) {
24486                 fprintf(fp, "\t/* call */\n");
24487         }
24488 #endif
24489         fprintf(fp, "\t%s L%s%lu\n",
24490                 bop, 
24491                 state->compiler->label_prefix,
24492                 (unsigned long)(TARG(branch, 0)->u.cval));
24493 }
24494
24495 static void print_op_ret(struct compile_state *state,
24496         struct triple *branch, FILE *fp)
24497 {
24498         fprintf(fp, "\tjmp *%s\n",
24499                 reg(state, RHS(branch, 0), REGCM_GPR32));
24500 }
24501
24502 static void print_op_set(struct compile_state *state,
24503         struct triple *set, FILE *fp)
24504 {
24505         const char *sop = "set";
24506         if (set->rhs != 1) {
24507                 internal_error(state, set, "setcc without condition?");
24508         }
24509         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24510         if ((RHS(set, 0)->op != OP_CMP) &&
24511                 (RHS(set, 0)->op != OP_TEST)) {
24512                 internal_error(state, set, "bad set test");
24513         }
24514         if (RHS(set, 0)->next != set) {
24515                 internal_error(state, set, "set does not follow test");
24516         }
24517         switch(set->op) {
24518         case OP_SET_EQ:       sop = "setz";  break;
24519         case OP_SET_NOTEQ:    sop = "setnz"; break;
24520         case OP_SET_SLESS:    sop = "setl";  break;
24521         case OP_SET_ULESS:    sop = "setb";  break;
24522         case OP_SET_SMORE:    sop = "setg";  break;
24523         case OP_SET_UMORE:    sop = "seta";  break;
24524         case OP_SET_SLESSEQ:  sop = "setle"; break;
24525         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24526         case OP_SET_SMOREEQ:  sop = "setge"; break;
24527         case OP_SET_UMOREEQ:  sop = "setae"; break;
24528         default:
24529                 internal_error(state, set, "Invalid set op");
24530                 break;
24531         }
24532         fprintf(fp, "\t%s %s\n",
24533                 sop, reg(state, set, REGCM_GPR8_LO));
24534 }
24535
24536 static void print_op_bit_scan(struct compile_state *state, 
24537         struct triple *ins, FILE *fp) 
24538 {
24539         const char *op;
24540         switch(ins->op) {
24541         case OP_BSF: op = "bsf"; break;
24542         case OP_BSR: op = "bsr"; break;
24543         default: 
24544                 internal_error(state, ins, "unknown bit scan");
24545                 op = 0;
24546                 break;
24547         }
24548         fprintf(fp, 
24549                 "\t%s %s, %s\n"
24550                 "\tjnz 1f\n"
24551                 "\tmovl $-1, %s\n"
24552                 "1:\n",
24553                 op,
24554                 reg(state, RHS(ins, 0), REGCM_GPR32),
24555                 reg(state, ins, REGCM_GPR32),
24556                 reg(state, ins, REGCM_GPR32));
24557 }
24558
24559
24560 static void print_sdecl(struct compile_state *state,
24561         struct triple *ins, FILE *fp)
24562 {
24563         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24564         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
24565         fprintf(fp, "L%s%lu:\n", 
24566                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24567         print_const(state, MISC(ins, 0), fp);
24568         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24569                 
24570 }
24571
24572 static void print_instruction(struct compile_state *state,
24573         struct triple *ins, FILE *fp)
24574 {
24575         /* Assumption: after I have exted the register allocator
24576          * everything is in a valid register. 
24577          */
24578         switch(ins->op) {
24579         case OP_ASM:
24580                 print_op_asm(state, ins, fp);
24581                 break;
24582         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24583         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24584         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24585         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24586         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24587         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24588         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24589         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24590         case OP_POS:    break;
24591         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24592         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24593         case OP_NOOP:
24594         case OP_INTCONST:
24595         case OP_ADDRCONST:
24596         case OP_BLOBCONST:
24597                 /* Don't generate anything here for constants */
24598         case OP_PHI:
24599                 /* Don't generate anything for variable declarations. */
24600                 break;
24601         case OP_UNKNOWNVAL:
24602                 fprintf(fp, " /* unknown %s */\n",
24603                         reg(state, ins, REGCM_ALL));
24604                 break;
24605         case OP_SDECL:
24606                 print_sdecl(state, ins, fp);
24607                 break;
24608         case OP_COPY:   
24609         case OP_CONVERT:
24610                 print_op_move(state, ins, fp);
24611                 break;
24612         case OP_LOAD:
24613                 print_op_load(state, ins, fp);
24614                 break;
24615         case OP_STORE:
24616                 print_op_store(state, ins, fp);
24617                 break;
24618         case OP_SMUL:
24619                 print_op_smul(state, ins, fp);
24620                 break;
24621         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24622         case OP_TEST:   print_op_test(state, ins, fp); break;
24623         case OP_JMP:
24624         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24625         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24626         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24627         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24628         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24629         case OP_CALL:
24630                 print_op_branch(state, ins, fp);
24631                 break;
24632         case OP_RET:
24633                 print_op_ret(state, ins, fp);
24634                 break;
24635         case OP_SET_EQ:      case OP_SET_NOTEQ:
24636         case OP_SET_SLESS:   case OP_SET_ULESS:
24637         case OP_SET_SMORE:   case OP_SET_UMORE:
24638         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24639         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24640                 print_op_set(state, ins, fp);
24641                 break;
24642         case OP_INB:  case OP_INW:  case OP_INL:
24643                 print_op_in(state, ins, fp); 
24644                 break;
24645         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24646                 print_op_out(state, ins, fp); 
24647                 break;
24648         case OP_BSF:
24649         case OP_BSR:
24650                 print_op_bit_scan(state, ins, fp);
24651                 break;
24652         case OP_RDMSR:
24653                 after_lhs(state, ins);
24654                 fprintf(fp, "\trdmsr\n");
24655                 break;
24656         case OP_WRMSR:
24657                 fprintf(fp, "\twrmsr\n");
24658                 break;
24659         case OP_HLT:
24660                 fprintf(fp, "\thlt\n");
24661                 break;
24662         case OP_SDIVT:
24663                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24664                 break;
24665         case OP_UDIVT:
24666                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24667                 break;
24668         case OP_UMUL:
24669                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24670                 break;
24671         case OP_LABEL:
24672                 if (!ins->use) {
24673                         return;
24674                 }
24675                 fprintf(fp, "L%s%lu:\n", 
24676                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24677                 break;
24678         case OP_ADECL:
24679                 /* Ignore adecls with no registers error otherwise */
24680                 if (!noop_adecl(ins)) {
24681                         internal_error(state, ins, "adecl remains?");
24682                 }
24683                 break;
24684                 /* Ignore OP_PIECE */
24685         case OP_PIECE:
24686                 break;
24687                 /* Operations that should never get here */
24688         case OP_SDIV: case OP_UDIV:
24689         case OP_SMOD: case OP_UMOD:
24690         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24691         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24692         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24693         default:
24694                 internal_error(state, ins, "unknown op: %d %s",
24695                         ins->op, tops(ins->op));
24696                 break;
24697         }
24698 }
24699
24700 static void print_instructions(struct compile_state *state)
24701 {
24702         struct triple *first, *ins;
24703         int print_location;
24704         struct occurance *last_occurance;
24705         FILE *fp;
24706         int max_inline_depth;
24707         max_inline_depth = 0;
24708         print_location = 1;
24709         last_occurance = 0;
24710         fp = state->output;
24711         /* Masks for common sizes */
24712         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24713         fprintf(fp, ".balign 16\n");
24714         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24715         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24716         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24717         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24718         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24719         first = state->first;
24720         ins = first;
24721         do {
24722                 if (print_location && 
24723                         last_occurance != ins->occurance) {
24724                         if (!ins->occurance->parent) {
24725                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24726                                         ins->occurance->function,
24727                                         ins->occurance->filename,
24728                                         ins->occurance->line,
24729                                         ins->occurance->col);
24730                         }
24731                         else {
24732                                 struct occurance *ptr;
24733                                 int inline_depth;
24734                                 fprintf(fp, "\t/*\n");
24735                                 inline_depth = 0;
24736                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24737                                         inline_depth++;
24738                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24739                                                 ptr->function,
24740                                                 ptr->filename,
24741                                                 ptr->line,
24742                                                 ptr->col);
24743                                 }
24744                                 fprintf(fp, "\t */\n");
24745                                 if (inline_depth > max_inline_depth) {
24746                                         max_inline_depth = inline_depth;
24747                                 }
24748                         }
24749                         if (last_occurance) {
24750                                 put_occurance(last_occurance);
24751                         }
24752                         get_occurance(ins->occurance);
24753                         last_occurance = ins->occurance;
24754                 }
24755
24756                 print_instruction(state, ins, fp);
24757                 ins = ins->next;
24758         } while(ins != first);
24759         if (print_location) {
24760                 fprintf(fp, "/* max inline depth %d */\n",
24761                         max_inline_depth);
24762         }
24763 }
24764
24765 static void generate_code(struct compile_state *state)
24766 {
24767         generate_local_labels(state);
24768         print_instructions(state);
24769         
24770 }
24771
24772 static void print_preprocessed_tokens(struct compile_state *state)
24773 {
24774         int tok;
24775         FILE *fp;
24776         int line;
24777         const char *filename;
24778         fp = state->output;
24779         filename = 0;
24780         line = 0;
24781         for(;;) {
24782                 struct file_state *file;
24783                 struct token *tk;
24784                 const char *token_str;
24785                 tok = peek(state);
24786                 if (tok == TOK_EOF) {
24787                         break;
24788                 }
24789                 tk = eat(state, tok);
24790                 token_str = 
24791                         tk->ident ? tk->ident->name :
24792                         tk->str_len ? tk->val.str :
24793                         tokens[tk->tok];
24794
24795                 file = state->file;
24796                 while(file->macro && file->prev) {
24797                         file = file->prev;
24798                 }
24799                 if (!file->macro && 
24800                         ((file->line != line) || (file->basename != filename))) 
24801                 {
24802                         int i, col;
24803                         if ((file->basename == filename) &&
24804                                 (line < file->line)) {
24805                                 while(line < file->line) {
24806                                         fprintf(fp, "\n");
24807                                         line++;
24808                                 }
24809                         }
24810                         else {
24811                                 fprintf(fp, "\n#line %d \"%s\"\n",
24812                                         file->line, file->basename);
24813                         }
24814                         line = file->line;
24815                         filename = file->basename;
24816                         col = get_col(file) - strlen(token_str);
24817                         for(i = 0; i < col; i++) {
24818                                 fprintf(fp, " ");
24819                         }
24820                 }
24821                 
24822                 fprintf(fp, "%s ", token_str);
24823                 
24824                 if (state->compiler->debug & DEBUG_TOKENS) {
24825                         loc(state->dbgout, state, 0);
24826                         fprintf(state->dbgout, "%s <- `%s'\n",
24827                                 tokens[tok], token_str);
24828                 }
24829         }
24830 }
24831
24832 static void compile(const char *filename, 
24833         struct compiler_state *compiler, struct arch_state *arch)
24834 {
24835         int i;
24836         struct compile_state state;
24837         struct triple *ptr;
24838         memset(&state, 0, sizeof(state));
24839         state.compiler = compiler;
24840         state.arch     = arch;
24841         state.file = 0;
24842         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24843                 memset(&state.token[i], 0, sizeof(state.token[i]));
24844                 state.token[i].tok = -1;
24845         }
24846         /* Remember the output descriptors */
24847         state.errout = stderr;
24848         state.dbgout = stdout;
24849         /* Remember the output filename */
24850         state.output    = fopen(state.compiler->ofilename, "w");
24851         if (!state.output) {
24852                 error(&state, 0, "Cannot open output file %s\n",
24853                         state.compiler->ofilename);
24854         }
24855         /* Make certain a good cleanup happens */
24856         exit_state = &state;
24857         atexit(exit_cleanup);
24858
24859         /* Prep the preprocessor */
24860         state.if_depth = 0;
24861         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24862         /* register the C keywords */
24863         register_keywords(&state);
24864         /* register the keywords the macro preprocessor knows */
24865         register_macro_keywords(&state);
24866         /* generate some builtin macros */
24867         register_builtin_macros(&state);
24868         /* Memorize where some special keywords are. */
24869         state.i_switch        = lookup(&state, "switch", 6);
24870         state.i_case          = lookup(&state, "case", 4);
24871         state.i_continue      = lookup(&state, "continue", 8);
24872         state.i_break         = lookup(&state, "break", 5);
24873         state.i_default       = lookup(&state, "default", 7);
24874         state.i_return        = lookup(&state, "return", 6);
24875         /* Memorize where predefined macros are. */
24876         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24877         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24878         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24879         /* Memorize where predefined identifiers are. */
24880         state.i___func__      = lookup(&state, "__func__", 8);
24881         /* Memorize where some attribute keywords are. */
24882         state.i_noinline      = lookup(&state, "noinline", 8);
24883         state.i_always_inline = lookup(&state, "always_inline", 13);
24884
24885         /* Process the command line macros */
24886         process_cmdline_macros(&state);
24887
24888         /* Allocate beginning bounding labels for the function list */
24889         state.first = label(&state);
24890         state.first->id |= TRIPLE_FLAG_VOLATILE;
24891         use_triple(state.first, state.first);
24892         ptr = label(&state);
24893         ptr->id |= TRIPLE_FLAG_VOLATILE;
24894         use_triple(ptr, ptr);
24895         flatten(&state, state.first, ptr);
24896
24897         /* Allocate a label for the pool of global variables */
24898         state.global_pool = label(&state);
24899         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24900         flatten(&state, state.first, state.global_pool);
24901
24902         /* Enter the globl definition scope */
24903         start_scope(&state);
24904         register_builtins(&state);
24905         compile_file(&state, filename, 1);
24906
24907         /* Stop if all we want is preprocessor output */
24908         if (state.compiler->flags & COMPILER_PP_ONLY) {
24909                 print_preprocessed_tokens(&state);
24910                 return;
24911         }
24912
24913         decls(&state);
24914
24915         /* Exit the global definition scope */
24916         end_scope(&state);
24917
24918         /* Now that basic compilation has happened 
24919          * optimize the intermediate code 
24920          */
24921         optimize(&state);
24922
24923         generate_code(&state);
24924         if (state.compiler->debug) {
24925                 fprintf(state.errout, "done\n");
24926         }
24927         exit_state = 0;
24928 }
24929
24930 static void version(FILE *fp)
24931 {
24932         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
24933 }
24934
24935 static void usage(void)
24936 {
24937         FILE *fp = stdout;
24938         version(fp);
24939         fprintf(fp,
24940                 "\nUsage: romcc [options] <source>.c\n"
24941                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
24942                 "Options: \n"
24943                 "-o <output file name>\n"
24944                 "-f<option>            Specify a generic compiler option\n"
24945                 "-m<option>            Specify a arch dependent option\n"
24946                 "--                    Specify this is the last option\n"
24947                 "\nGeneric compiler options:\n"
24948         );
24949         compiler_usage(fp);
24950         fprintf(fp,
24951                 "\nArchitecture compiler options:\n"
24952         );
24953         arch_usage(fp);
24954         fprintf(fp,
24955                 "\n"
24956         );
24957 }
24958
24959 static void arg_error(char *fmt, ...)
24960 {
24961         va_list args;
24962         va_start(args, fmt);
24963         vfprintf(stderr, fmt, args);
24964         va_end(args);
24965         usage();
24966         exit(1);
24967 }
24968
24969 int main(int argc, char **argv)
24970 {
24971         const char *filename;
24972         struct compiler_state compiler;
24973         struct arch_state arch;
24974         int all_opts;
24975         
24976         
24977         /* I don't want any surprises */
24978         setlocale(LC_ALL, "C");
24979
24980         init_compiler_state(&compiler);
24981         init_arch_state(&arch);
24982         filename = 0;
24983         all_opts = 0;
24984         while(argc > 1) {
24985                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
24986                         compiler.ofilename = argv[2];
24987                         argv += 2;
24988                         argc -= 2;
24989                 }
24990                 else if (!all_opts && argv[1][0] == '-') {
24991                         int result;
24992                         result = -1;
24993                         if (strcmp(argv[1], "--") == 0) {
24994                                 result = 0;
24995                                 all_opts = 1;
24996                         }
24997                         else if (strncmp(argv[1], "-E", 2) == 0) {
24998                                 result = compiler_encode_flag(&compiler, argv[1]);
24999                         }
25000                         else if (strncmp(argv[1], "-O", 2) == 0) {
25001                                 result = compiler_encode_flag(&compiler, argv[1]);
25002                         }
25003                         else if (strncmp(argv[1], "-I", 2) == 0) {
25004                                 result = compiler_encode_flag(&compiler, argv[1]);
25005                         }
25006                         else if (strncmp(argv[1], "-D", 2) == 0) {
25007                                 result = compiler_encode_flag(&compiler, argv[1]);
25008                         }
25009                         else if (strncmp(argv[1], "-U", 2) == 0) {
25010                                 result = compiler_encode_flag(&compiler, argv[1]);
25011                         }
25012                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
25013                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25014                         }
25015                         else if (strncmp(argv[1], "-f", 2) == 0) {
25016                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25017                         }
25018                         else if (strncmp(argv[1], "-m", 2) == 0) {
25019                                 result = arch_encode_flag(&arch, argv[1]+2);
25020                         }
25021                         if (result < 0) {
25022                                 arg_error("Invalid option specified: %s\n",
25023                                         argv[1]);
25024                         }
25025                         argv++;
25026                         argc--;
25027                 }
25028                 else {
25029                         if (filename) {
25030                                 arg_error("Only one filename may be specified\n");
25031                         }
25032                         filename = argv[1];
25033                         argv++;
25034                         argc--;
25035                 }
25036         }
25037         if (!filename) {
25038                 arg_error("No filename specified\n");
25039         }
25040         compile(filename, &compiler, &arch);
25041
25042         return 0;
25043 }