romcc:
[coreboot.git] / util / romcc / romcc.c
index e72ce90c6678b5f8947105eff36079523fb67cfb..5712f34040d2b98fc96c04bc49db95d54c5a90e8 100644 (file)
@@ -3,8 +3,8 @@
 #undef RELEASE_DATE
 #undef VERSION
 #define VERSION_MAJOR "0"
-#define VERSION_MINOR "68"
-#define RELEASE_DATE "15 November 2004"
+#define VERSION_MINOR "71"
+#define RELEASE_DATE "03 April 2009"
 #define VERSION VERSION_MAJOR "." VERSION_MINOR
 
 #include <stdarg.h>
 #define MAX_CWD_SIZE 4096
 #define MAX_ALLOCATION_PASSES 100
 
+/* NOTE: Before you even start thinking to touch anything 
+ * in this code, set DEBUG_ROMCC_WARNINGS to 1 to get an
+ * insight on the original author's thoughts. We introduced 
+ * this switch as romcc was about the only thing producing
+ * massive warnings in our code..
+ */
+#define DEBUG_ROMCC_WARNINGS 0
+
 #define DEBUG_CONSISTENCY 1
 #define DEBUG_SDP_BLOCKS 0
 #define DEBUG_TRIPLE_COLOR 0
 
 #define DEBUG_EXPLICIT_CLOSURES 0
 
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME give clear error messages about unused variables"
 #warning "FIXME properly handle multi dimensional arrays"
 #warning "FIXME handle multiple register sizes"
+#endif
 
 /*  Control flow graph of a loop without goto.
  * 
@@ -209,11 +219,10 @@ static int exists(const char *dirname, const char *filename)
 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
 {
        char cwd[MAX_CWD_SIZE];
-       int fd;
        char *buf;
        off_t size, progress;
        ssize_t result;
-       struct stat stats;
+       FILE* file;
        
        if (!filename) {
                *r_size = 0;
@@ -223,25 +232,22 @@ static char *slurp_file(const char *dirname, const char *filename, off_t *r_size
                die("cwd buffer to small");
        }
        xchdir(dirname);
-       fd = open(filename, O_RDONLY);
+       file = fopen(filename, "rb");
        xchdir(cwd);
-       if (fd < 0) {
+       if (file == NULL) {
                die("Cannot open '%s' : %s\n",
                        filename, strerror(errno));
        }
-       result = fstat(fd, &stats);
-       if (result < 0) {
-               die("Cannot stat: %s: %s\n",
-                       filename, strerror(errno));
-       }
-       size = stats.st_size;
+       fseek(file, 0, SEEK_END);
+       size = ftell(file);
+       fseek(file, 0, SEEK_SET);
        *r_size = size +1;
        buf = xmalloc(size +2, filename);
        buf[size] = '\n'; /* Make certain the file is newline terminated */
        buf[size+1] = '\0'; /* Null terminate the file for good measure */
        progress = 0;
        while(progress < size) {
-               result = read(fd, buf + progress, size - progress);
+               result = fread(buf + progress, 1, size - progress, file);
                if (result < 0) {
                        if ((errno == EINTR) || (errno == EAGAIN))
                                continue;
@@ -250,16 +256,14 @@ static char *slurp_file(const char *dirname, const char *filename, off_t *r_size
                }
                progress += result;
        }
-       result = close(fd);
-       if (result < 0) {
-               die("Close of %s failed: %s\n",
-                       filename, strerror(errno));
-       }
+       fclose(file);
        return buf;
 }
 
 /* Types on the destination platform */
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME this assumes 32bit x86 is the destination"
+#endif
 typedef int8_t   schar_t;
 typedef uint8_t  uchar_t;
 typedef int8_t   char_t;
@@ -268,7 +272,7 @@ typedef uint16_t ushort_t;
 typedef int32_t  int_t;
 typedef uint32_t uint_t;
 typedef int32_t  long_t;
-typedef uint32_t ulong_t;
+#define ulong_t uint32_t
 
 #define SCHAR_T_MIN (-128)
 #define SCHAR_T_MAX 127
@@ -800,7 +804,9 @@ static const struct op_info table_ops[] = {
 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
 [OP_UNKNOWNVAL ] = OP( 0,  0, 0, 0, PURE | DEF, "unknown"),
 
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME is it correct for OP_WRITE to be a def?  I currently use it as one..."
+#endif
 [OP_WRITE      ] = OP( 0,  1, 1, 0, PURE | DEF | BLOCK, "write"),
 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
@@ -1754,7 +1760,7 @@ static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
                state->file->report_name, state->file->report_line, col);
 }
 
-static void internal_error(struct compile_state *state, struct triple *ptr, 
+static void __attribute__ ((noreturn)) internal_error(struct compile_state *state, struct triple *ptr, 
        const char *fmt, ...)
 {
        FILE *fp = state->errout;
@@ -1792,7 +1798,7 @@ static void internal_warning(struct compile_state *state, struct triple *ptr,
 
 
 
-static void error(struct compile_state *state, struct triple *ptr, 
+static void __attribute__ ((noreturn)) error(struct compile_state *state, struct triple *ptr, 
        const char *fmt, ...)
 {
        FILE *fp = state->errout;
@@ -1847,6 +1853,7 @@ static void valid_ins(struct compile_state *state, struct triple *ptr)
        valid_op(state, ptr->op);
 }
 
+#if DEBUG_ROMCC_WARNING
 static void valid_param_count(struct compile_state *state, struct triple *ins)
 {
        int lhs, rhs, misc, targ;
@@ -1869,6 +1876,7 @@ static void valid_param_count(struct compile_state *state, struct triple *ins)
                internal_error(state, ins, "Bad targ count");
        }
 }
+#endif
 
 static struct type void_type;
 static struct type unknown_type;
@@ -2643,13 +2651,15 @@ static int triple_is_ret(struct compile_state *state, struct triple *ins)
        /* Is this triple a return instruction? */
        return triple_is_branch_type(state, ins, RETBRANCH);
 }
-
+#if DEBUG_ROMCC_WARNING
 static int triple_is_simple_ubranch(struct compile_state *state, struct triple *ins)
 {
        /* Is this triple an unconditional branch and not a call or a
         * return? */
        return triple_is_branch_type(state, ins, UBRANCH);
 }
+#endif
 
 static int triple_is_end(struct compile_state *state, struct triple *ins)
 {
@@ -2925,7 +2935,10 @@ static int find_rhs_use(struct compile_state *state,
        struct triple **param;
        int size, i;
        verify_use(state, user, used);
+
+#if DEBUG_ROMCC_WARNINGS
 #warning "AUDIT ME ->rhs"
+#endif
        size = user->rhs;
        param = &RHS(user, 0);
        for(i = 0; i < size; i++) {
@@ -3603,6 +3616,7 @@ static void register_builtin_macros(struct compile_state *state)
        tm = localtime(&now);
 
        register_builtin_macro(state, "__ROMCC__", VERSION_MAJOR);
+       register_builtin_macro(state, "__PRE_RAM__", VERSION_MAJOR);
        register_builtin_macro(state, "__ROMCC_MINOR__", VERSION_MINOR);
        register_builtin_macro(state, "__FILE__", "\"This should be the filename\"");
        register_builtin_macro(state, "__LINE__", "54321");
@@ -3842,15 +3856,16 @@ static const char *next_char(struct file_state *file, const char *pos, int index
                }
                /* Is this an escaped newline? */
                if (file->join_lines &&
-                       (c == '\\') && (pos + size < end) && (pos[1] == '\n')) 
+                       (c == '\\') && (pos + size < end) && ((pos[1] == '\n') || ((pos[1] == '\r') && (pos[2] == '\n'))))
                {
+                       int cr_offset = ((pos[1] == '\r') && (pos[2] == '\n'))?1:0;
                        /* At the start of a line just eat it */
                        if (pos == file->pos) {
                                file->line++;
                                file->report_line++;
-                               file->line_start = pos + size + 1;
+                               file->line_start = pos + size + 1 + cr_offset;
                        }
-                       pos += size + 1;
+                       pos += size + 1 + cr_offset;
                }
                /* Do I need to ga any farther? */
                else if (index == 0) {
@@ -4028,10 +4043,15 @@ static void raw_next_token(struct compile_state *state,
                tok = TOK_SPACE;
                tokp = next_char(file, tokp, 1);
                while((c = get_char(file, tokp)) != -1) {
-                       tokp = next_char(file, tokp, 1);
+                       /* Advance to the next character only after we verify
+                        * the current character is not a newline.  
+                        * EOL is special to the preprocessor so we don't
+                        * want to loose any.
+                        */
                        if (c == '\n') {
                                break;
                        }
+                       tokp = next_char(file, tokp, 1);
                }
        }
        /* Comments */
@@ -4312,7 +4332,7 @@ static void check_tok(struct compile_state *state, struct token *tk, int tok)
 
 struct macro_arg_value {
        struct hash_entry *ident;
-       unsigned char *value;
+       char *value;
        size_t len;
 };
 static struct macro_arg_value *read_macro_args(
@@ -4373,7 +4393,7 @@ static struct macro_arg_value *read_macro_args(
                len = char_strlen(file, start, file->pos);
                argv[i].value = xrealloc(
                        argv[i].value, argv[i].len + len, "macro args");
-               char_strcpy(argv[i].value + argv[i].len, file, start, file->pos);
+               char_strcpy((char *)argv[i].value + argv[i].len, file, start, file->pos);
                argv[i].len += len;
        }
        if (i != macro->argc -1) {
@@ -4454,7 +4474,7 @@ static void macro_expand_args(struct compile_state *state,
                fmacro.prev        = 0;
                fmacro.basename    = argv[i].ident->name;
                fmacro.dirname     = "";
-               fmacro.buf         = argv[i].value;
+               fmacro.buf         = (char *)argv[i].value;
                fmacro.size        = argv[i].len;
                fmacro.pos         = fmacro.buf;
                fmacro.line        = 1;
@@ -5062,7 +5082,7 @@ static void compile_file(struct compile_state *state, const char *filename, int
        if (getcwd(cwd, sizeof(cwd)) == 0) {
                die("cwd buffer to small");
        }
-       if (subdir[0] == '/') {
+       if ((subdir[0] == '/') || ((subdir[1] == ':') && ((subdir[2] == '/') || (subdir[2] == '\\')))) {
                file->dirname = xmalloc(subdir_len + 1, "dirname");
                memcpy(file->dirname, subdir, subdir_len);
                file->dirname[subdir_len] = '\0';
@@ -5434,6 +5454,13 @@ static void preprocess(struct compile_state *state, struct token *current_token)
                name = 0;
 
                pp_eat(state, TOK_MINCLUDE);
+               if (if_eat(state)) {
+                       /* Find the end of the line */
+                       while((tok = raw_peek(state)) != TOK_EOL) {
+                               raw_eat(state, tok);
+                       }
+                       break;
+               }
                tok = peek(state);
                if (tok == TOK_LIT_STRING) {
                        struct token *tk;
@@ -5620,7 +5647,7 @@ static struct type *invalid_type(struct compile_state *state, struct type *type)
 static inline ulong_t mask_uint(ulong_t x)
 {
        if (SIZEOF_INT < SIZEOF_LONG) {
-               ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT))) -1;
+               ulong_t mask = (1ULL << ((ulong_t)(SIZEOF_INT))) -1;
                x &= mask;
        }
        return x;
@@ -5631,7 +5658,9 @@ static inline ulong_t mask_uint(ulong_t x)
 static struct type void_type    = { .type  = TYPE_VOID };
 static struct type char_type    = { .type  = TYPE_CHAR };
 static struct type uchar_type   = { .type  = TYPE_UCHAR };
+#if DEBUG_ROMCC_WARNING
 static struct type short_type   = { .type  = TYPE_SHORT };
+#endif
 static struct type ushort_type  = { .type  = TYPE_USHORT };
 static struct type int_type     = { .type  = TYPE_INT };
 static struct type uint_type    = { .type  = TYPE_UINT };
@@ -5644,11 +5673,13 @@ static struct type void_ptr_type  = {
        .left = &void_type,
 };
 
+#if DEBUG_ROMCC_WARNING
 static struct type void_func_type = { 
        .type  = TYPE_FUNCTION,
        .left  = &void_type,
        .right = &void_type,
 };
+#endif
 
 static size_t bits_to_bytes(size_t size)
 {
@@ -7389,7 +7420,9 @@ static struct triple *read_expr(struct compile_state *state, struct triple *def)
        if  (!def) {
                return 0;
        }
+#if DEBUG_ROMCC_WARNINGS
 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
+#endif
        /* Transform lvalues into something we can read */
        def = lvalue_conversion(state, def);
        if (!is_lvalue(state, def)) {
@@ -7730,7 +7763,9 @@ static struct triple *mkcond_expr(
 
 static int expr_depth(struct compile_state *state, struct triple *ins)
 {
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
+#endif
        int count;
        count = 0;
        if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
@@ -8344,6 +8379,7 @@ static int is_one(struct triple *ins)
        return is_simple_const(ins) && (ins->u.cval == 1);
 }
 
+#if DEBUG_ROMCC_WARNING
 static long_t bit_count(ulong_t value)
 {
        int count;
@@ -8360,6 +8396,8 @@ static long_t bit_count(ulong_t value)
        return count;
        
 }
+#endif
+
 static long_t bsr(ulong_t value)
 {
        int i;
@@ -8577,6 +8615,7 @@ static void unuse_lhs(struct compile_state *state, struct triple *ins)
        }
 }
 
+#if DEBUG_ROMCC_WARNING
 static void unuse_misc(struct compile_state *state, struct triple *ins)
 {
        struct triple **expr;
@@ -8607,6 +8646,7 @@ static void check_lhs(struct compile_state *state, struct triple *ins)
        }
        
 }
+#endif
 
 static void check_misc(struct compile_state *state, struct triple *ins)
 {
@@ -8644,6 +8684,7 @@ static void wipe_ins(struct compile_state *state, struct triple *ins)
        ins->targ = 0;
 }
 
+#if DEBUG_ROMCC_WARNING
 static void wipe_branch(struct compile_state *state, struct triple *ins)
 {
        /* Becareful which instructions you replace the wiped
@@ -8659,6 +8700,7 @@ static void wipe_branch(struct compile_state *state, struct triple *ins)
        ins->misc = 0;
        ins->targ = 0;
 }
+#endif
 
 static void mkcopy(struct compile_state *state, 
        struct triple *ins, struct triple *rhs)
@@ -10631,7 +10673,9 @@ static struct type *declarator(
        struct hash_entry **ident, int need_ident);
 static void decl(struct compile_state *state, struct triple *first);
 static struct type *specifier_qualifier_list(struct compile_state *state);
+#if DEBUG_ROMCC_WARNING
 static int isdecl_specifier(int tok);
+#endif
 static struct type *decl_specifiers(struct compile_state *state);
 static int istype(int tok);
 static struct triple *expr(struct compile_state *state);
@@ -10697,7 +10741,7 @@ static struct triple *character_constant(struct compile_state *state)
        int c;
        int str_len;
        tk = eat(state, TOK_LIT_CHAR);
-       str = tk->val.str + 1;
+       str = (signed char *)tk->val.str + 1;
        str_len = tk->str_len - 2;
        if (str_len <= 0) {
                error(state, 0, "empty character constant");
@@ -10726,7 +10770,7 @@ static struct triple *string_constant(struct compile_state *state)
        /* The while loop handles string concatenation */
        do {
                tk = eat(state, TOK_LIT_STRING);
-               str = tk->val.str + 1;
+               str = (signed char *)tk->val.str + 1;
                str_len = tk->str_len - 2;
                if (str_len < 0) {
                        error(state, 0, "negative string constant length");
@@ -11169,7 +11213,9 @@ static struct triple *shift_expr(struct compile_state *state)
 
 static struct triple *relational_expr(struct compile_state *state)
 {
+#if DEBUG_ROMCC_WARNINGS
 #warning "Extend relational exprs to work on more than arithmetic types"
+#endif
        struct triple *def;
        int done;
        def = shift_expr(state);
@@ -11212,7 +11258,9 @@ static struct triple *relational_expr(struct compile_state *state)
 
 static struct triple *equality_expr(struct compile_state *state)
 {
+#if DEBUG_ROMCC_WARNINGS
 #warning "Extend equality exprs to work on more than arithmetic types"
+#endif
        struct triple *def;
        int done;
        def = relational_expr(state);
@@ -11773,7 +11821,9 @@ static void return_statement(struct compile_state *state, struct triple *first)
        int last;
        eat(state, TOK_RETURN);
 
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME implement a more general excess branch elimination"
+#endif
        val = 0;
        /* If we have a return value do some more work */
        if (peek(state) != TOK_SEMI) {
@@ -12948,6 +12998,7 @@ static struct type *specifier_qualifier_list(struct compile_state *state)
        return type;
 }
 
+#if DEBUG_ROMCC_WARNING
 static int isdecl_specifier(int tok)
 {
        switch(tok) {
@@ -12985,6 +13036,7 @@ static int isdecl_specifier(int tok)
                return 0;
        }
 }
+#endif
 
 static struct type *decl_specifiers(struct compile_state *state)
 {
@@ -13067,7 +13119,9 @@ static struct triple *initializer(
        struct compile_state *state, struct type *type)
 {
        struct triple *result;
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
+#endif
        if (peek(state) != TOK_LBRACE) {
                result = assignment_expr(state);
                if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
@@ -13515,8 +13569,10 @@ static struct reg_block *compute_variable_lifetimes(
        struct compile_state *state, struct basic_blocks *bb);
 static void free_variable_lifetimes(struct compile_state *state, 
        struct basic_blocks *bb, struct reg_block *blocks);
+#if DEBUG_EXPLICIT_CLOSURES
 static void print_live_variables(struct compile_state *state, 
        struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
+#endif
 
 
 static struct triple *call(struct compile_state *state,
@@ -15093,7 +15149,9 @@ static void free_basic_block(struct compile_state *state, struct block *block)
                }
        }
        memset(block, -1, sizeof(*block));
+#ifndef WIN32
        xfree(block);
+#endif
 }
 
 static void free_basic_blocks(struct compile_state *state, 
@@ -17307,19 +17365,24 @@ static int in_triple(struct reg_block *rb, struct triple *in)
 {
        return do_triple_set(&rb->in, in, 0);
 }
+
+#if DEBUG_ROMCC_WARNING
 static void unin_triple(struct reg_block *rb, struct triple *unin)
 {
        do_triple_unset(&rb->in, unin);
 }
+#endif
 
 static int out_triple(struct reg_block *rb, struct triple *out)
 {
        return do_triple_set(&rb->out, out, 0);
 }
+#if DEBUG_ROMCC_WARNING
 static void unout_triple(struct reg_block *rb, struct triple *unout)
 {
        do_triple_unset(&rb->out, unout);
 }
+#endif
 
 static int initialize_regblock(struct reg_block *blocks,
        struct block *block, int vertex)
@@ -17485,7 +17548,9 @@ static int use_in(struct compile_state *state, struct reg_block *rb)
        /* Find the variables we use but don't define and add
         * it to the current blocks input set.
         */
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME is this O(N^2) algorithm bad?"
+#endif
        struct block *block;
        struct triple *ptr;
        int done;
@@ -17656,6 +17721,7 @@ struct print_live_variable_info {
        struct reg_block *rb;
        FILE *fp;
 };
+#if DEBUG_EXPLICIT_CLOSURES
 static void print_live_variables_block(
        struct compile_state *state, struct block *block, void *arg)
 
@@ -17737,7 +17803,7 @@ static void print_live_variables(struct compile_state *state,
        walk_blocks(state, bb, print_live_variables_block, &info);
 
 }
-
+#endif
 
 static int count_triples(struct compile_state *state)
 {
@@ -17908,7 +17974,10 @@ static void eliminate_inefectual_code(struct compile_state *state)
                        struct triple *last;
                        last = user->member->last;
                        while((last->op == OP_NOOP) && (last != user->member->first)) {
-                               internal_warning(state, last, "awakening noop?");
+#if DEBUG_ROMCC_WARNINGS
+#warning "Should we bring the awakening noops back?"
+#endif
+                               // internal_warning(state, last, "awakening noop?");
                                last = last->prev;
                        }
                        awaken(state, dtriple, &last, &work_list_tail);
@@ -18531,6 +18600,7 @@ static void transfer_live_edges(struct reg_state *rstate,
  *
  */
 
+#if DEBUG_ROMCC_WARNING
 static void different_colored(
        struct compile_state *state, struct reg_state *rstate, 
        struct triple *parent, struct triple *ins)
@@ -18550,7 +18620,7 @@ static void different_colored(
                }
        }
 }
-
+#endif
 
 static struct live_range *coalesce_ranges(
        struct compile_state *state, struct reg_state *rstate,
@@ -18638,7 +18708,9 @@ static struct live_range *coalesce_ranges(
 #endif
        
        /* Append lr2 onto lr1 */
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME should this be a merge instead of a splice?"
+#endif
        /* This FIXME item applies to the correctness of live_range_end 
         * and to the necessity of making multiple passes of coalesce_live_ranges.
         * A failure to find some coalesce opportunities in coaleace_live_ranges
@@ -18875,6 +18947,7 @@ static void graph_ins(
        return;
 }
 
+#if DEBUG_CONSISTENCY > 1
 static struct live_range *get_verify_live_range(
        struct compile_state *state, struct reg_state *rstate, struct triple *ins)
 {
@@ -18953,7 +19026,7 @@ static void verify_graph_ins(
        }
        return;
 }
-
+#endif
 
 static void print_interference_ins(
        struct compile_state *state, 
@@ -19190,7 +19263,9 @@ static void replace_block_use(struct compile_state *state,
        struct reg_block *blocks, struct triple *orig, struct triple *new)
 {
        int i;
+#if DEBUG_ROMCC_WARNINGS
 #warning "WISHLIST visit just those blocks that need it *"
+#endif
        for(i = 1; i <= state->bb.last_vertex; i++) {
                struct reg_block *rb;
                rb = &blocks[i];
@@ -19243,7 +19318,9 @@ static struct triple *resolve_tangle(
        struct triple_set *set, *next;
        struct triple *copy;
 
+#if DEBUG_ROMCC_WARNINGS
 #warning "WISHLIST recalculate all affected instructions colors"
+#endif
        info = find_lhs_color(state, tangle, 0);
        for(set = tangle->use; set; set = next) {
                struct triple *user;
@@ -19382,7 +19459,9 @@ struct triple *find_constrained_def(
                 * Then a triple is not constrained.
                 * FIXME handle this case!
                 */
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
+#endif
                
 
                /* Of the constrained live ranges deal with the
@@ -19418,7 +19497,9 @@ static int split_constrained_ranges(
        for(edge = range->edges; edge; edge = edge->next) {
                constrained = find_constrained_def(state, edge->node, constrained);
        }
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
+#endif
        if (!constrained) {
                constrained = find_constrained_def(state, range, constrained);
        }
@@ -19462,7 +19543,9 @@ static int split_ranges(
         * it would be useful to have.
         *
         */
+#if DEBUG_ROMCC_WARNINGS
 #warning "WISHLIST implement live range splitting..."
+#endif
        
        if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
                FILE *fp = state->errout;
@@ -20260,8 +20343,8 @@ static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
        struct ssa_edge *sedge)
 {
        if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
-               fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
-                       sedge - scc->ssa_edges,
+               fprintf(state->errout, "adding sedge: %5ld (%4d -> %5d)\n",
+                       (long)(sedge - scc->ssa_edges),
                        sedge->src->def->id,
                        sedge->dst->def->id);
        }
@@ -20270,8 +20353,8 @@ static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
                (sedge->work_prev != sedge)) {
 
                if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
-                       fprintf(state->errout, "dupped sedge: %5d\n",
-                               sedge - scc->ssa_edges);
+                       fprintf(state->errout, "dupped sedge: %5ld\n",
+                               (long)(sedge - scc->ssa_edges));
                }
                return;
        }
@@ -20627,7 +20710,9 @@ static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
                scratch->next = lnode->def->next;
        }
        /* Recompute the value */
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME see if simplify does anything bad"
+#endif
        /* So far it looks like only the strength reduction
         * optimization are things I need to worry about.
         */
@@ -20691,7 +20776,9 @@ static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
                ((      !triple_is_def(state, lnode->def)  &&
                        !triple_is_cbranch(state, lnode->def)) ||
                        (lnode->def->op == OP_PIECE))) {
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME constant propogate through expressions with multiple left hand sides"
+#endif
                if (changed) {
                        internal_warning(state, lnode->def, "non def changes value?");
                }
@@ -21012,7 +21099,7 @@ static void scc_transform(struct compile_state *state)
                        fblock = lnode->fblock;
 
                        if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
-                               fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
+                               fprintf(state->errout, "sedge: %5ld (%5d -> %5d)\n",
                                        sedge - scc.ssa_edges,
                                        sedge->src->def->id,
                                        sedge->dst->def->id);
@@ -21519,8 +21606,10 @@ static void optimize(struct compile_state *state)
        /* Propogate constants throughout the code */
        scc_transform(state);
        verify_consistency(state);
+#if DEBUG_ROMCC_WARNINGS
 #warning "WISHLIST implement single use constants (least possible register pressure)"
 #warning "WISHLIST implement induction variable elimination"
+#endif
        /* Select architecture instructions and an initial partial
         * coloring based on architecture constraints.
         */
@@ -21705,7 +21794,11 @@ static void print_op_asm(struct compile_state *state,
 #define REG_XMM7   44
 #define REGC_XMM_FIRST REG_XMM0
 #define REGC_XMM_LAST  REG_XMM7
+
+#if DEBUG_ROMCC_WARNINGS
 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
+#endif
+
 #define LAST_REG   REG_XMM7
 
 #define REGC_GPR32_8_FIRST REG_EAX
@@ -22283,7 +22376,10 @@ static int arch_select_free_register(
 
 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
 {
+
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME force types smaller (if legal) before I get here"
+#endif
        unsigned mask;
        mask = 0;
        switch(type->type & TYPE_MASK) {
@@ -23750,12 +23846,12 @@ static long get_const_pool_ref(
        long ref;
        ref = next_label(state);
        fprintf(fp, ".section \"" DATA_SECTION "\"\n");
-       fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
+       fprintf(fp, ".balign %ld\n", (long int)align_of_in_bytes(state, ins->type));
        fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
        print_const(state, ins, fp);
        fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
        if (fill_bytes) {
-               fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
+               fprintf(fp, ".fill %ld, 1, 0\n", (long int)fill_bytes);
        }
        fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
        return ref;
@@ -24458,7 +24554,9 @@ static void print_op_branch(struct compile_state *state,
                        (RHS(branch, 0)->op != OP_TEST)) {
                        internal_error(state, branch, "bad branch test");
                }
+#if DEBUG_ROMCC_WARNINGS
 #warning "FIXME I have observed instructions between the test and branch instructions"
+#endif
                ptr = RHS(branch, 0);
                for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
                        if (ptr->op != OP_COPY) {
@@ -24562,7 +24660,7 @@ static void print_sdecl(struct compile_state *state,
        struct triple *ins, FILE *fp)
 {
        fprintf(fp, ".section \"" DATA_SECTION "\"\n");
-       fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
+       fprintf(fp, ".balign %ld\n", (long int)align_of_in_bytes(state, ins->type));
        fprintf(fp, "L%s%lu:\n", 
                state->compiler->label_prefix, (unsigned long)(ins->u.cval));
        print_const(state, MISC(ins, 0), fp);
@@ -24724,8 +24822,8 @@ static void print_instructions(struct compile_state *state)
                        last_occurance != ins->occurance) {
                        if (!ins->occurance->parent) {
                                fprintf(fp, "\t/* %s,%s:%d.%d */\n",
-                                       ins->occurance->function,
-                                       ins->occurance->filename,
+                                       ins->occurance->function?ins->occurance->function:"(null)",
+                                       ins->occurance->filename?ins->occurance->filename:"(null)",
                                        ins->occurance->line,
                                        ins->occurance->col);
                        }
@@ -24830,7 +24928,7 @@ static void print_preprocessed_tokens(struct compile_state *state)
        }
 }
 
-static void compile(const char *filename, 
+static void compile(const char *filename, const char *includefile,
        struct compiler_state *compiler, struct arch_state *arch)
 {
        int i;
@@ -24903,7 +25001,10 @@ static void compile(const char *filename,
        /* Enter the globl definition scope */
        start_scope(&state);
        register_builtins(&state);
+
        compile_file(&state, filename, 1);
+       if (includefile)
+               compile_file(&state, includefile, 1);
 
        /* Stop if all we want is preprocessor output */
        if (state.compiler->flags & COMPILER_PP_ONLY) {
@@ -24970,6 +25071,7 @@ static void arg_error(char *fmt, ...)
 int main(int argc, char **argv)
 {
        const char *filename;
+       const char *includefile = NULL;
        struct compiler_state compiler;
        struct arch_state arch;
        int all_opts;
@@ -25019,6 +25121,16 @@ int main(int argc, char **argv)
                        else if (strncmp(argv[1], "-m", 2) == 0) {
                                result = arch_encode_flag(&arch, argv[1]+2);
                        }
+                       else if (strncmp(argv[1], "-include", 10) == 0) {
+                               if (includefile) {
+                                       arg_error("Only one -include option may be specified.\n");
+                               } else {
+                                       argv++;
+                                       argc--;
+                                       includefile = argv[1];
+                                       result = 0;
+                               }
+                       }
                        if (result < 0) {
                                arg_error("Invalid option specified: %s\n",
                                        argv[1]);
@@ -25038,7 +25150,7 @@ int main(int argc, char **argv)
        if (!filename) {
                arg_error("No filename specified\n");
        }
-       compile(filename, &compiler, &arch);
+       compile(filename, includefile, &compiler, &arch);
 
        return 0;
 }