- Update the romcc version.
authorEric Biederman <ebiederm@xmission.com>
Thu, 19 Jun 2003 15:14:52 +0000 (15:14 +0000)
committerEric Biederman <ebiederm@xmission.com>
Thu, 19 Jun 2003 15:14:52 +0000 (15:14 +0000)
- Add an additional consistency check to romcc and fix the more obvious problems it has uncovered
  With this update there are no known silent failures in romcc.
- Update the memory initialization code to setup all 3 of the memory sizing registers properly
- In auto.c test our dynamic maximum amount of ram.

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@885 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/mainboard/amd/solo/auto.c
src/mainboard/amd/solo/failover.c
src/northbridge/amd/amdk8/raminit.c
util/romcc/Makefile
util/romcc/romcc.c
util/romcc/tests/simple_test34.c [new file with mode: 0644]
util/romcc/tests/simple_test35.c [new file with mode: 0644]
util/romcc/tests/simple_test36.c [new file with mode: 0644]
util/romcc/tests/simple_test37.c [new file with mode: 0644]

index f61b79425619eea2b525d8096a970ba589de3273..94ce39d46454b4df57794ae228fe58cd6dc53552 100644 (file)
@@ -177,7 +177,6 @@ static void main(void)
                print_debug_hex32(msr.hi);
                print_debug_hex32(msr.lo);
                print_debug("\r\n");
-#warning "FIXME if I pass msr.lo somehow I get the value 0x00000030 as stop in ram_check"
-               ram_check(0x00000000, 0x20000000);
+               ram_check(0x00000000, msr.lo);
        }
 }
index cda8ea8076a0f46c8bc13e8b07a528c622a39dfb..da0f1d0302d214130a39fadc14ea16d75a56021c 100644 (file)
@@ -7,8 +7,6 @@
 #include "southbridge/amd/amd8111/amd8111_enable_rom.c"
 #include "northbridge/amd/amdk8/early_ht.c"
 
-
-
 static void main(void)
 {
        if (do_normal_boot()) {
index 54ca82e65abc8320d39edd651112851cf188e839..34d3ab1fa62d692d435977906a5bff39b3370ddd 100644 (file)
@@ -657,18 +657,20 @@ static void sdram_set_registers(void)
         *         address that define the memory address space.  These
         *         bits decode 32-MByte blocks of memory.
         */
-       PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000001,
 #if MEMORY_CONFIG == MEMORY_LNXI_SOLO
-       PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x01000001,
-       PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x02000001,
-       PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x03000001,
+       PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
 #endif
 #if MEMORY_CONFIG == MEMORY_SUSE_SOLO
+       PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000001,
        PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00800001,
        PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x01000001,
        PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x01800001,
 #endif
 #if MEMORY_CONFIG == MEMORY_LNXI_HDAMA
+       PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000001,
        PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00001001,
        PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
        PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
@@ -697,10 +699,10 @@ static void sdram_set_registers(void)
         * 
         */
 #if MEMORY_CONFIG == MEMORY_LNXI_SOLO
-       PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00e0fe00,
-       PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00e0fe00,
-       PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00e0fe00,
-       PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00e0fe00,
+       PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00000000,
 #endif
 #if MEMORY_CONFIG == MEMORY_SUSE_SOLO
        PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x0060fe00,
@@ -739,7 +741,7 @@ static void sdram_set_registers(void)
         * [31:15]
         */
 #if MEMORY_CONFIG == MEMORY_LNXI_SOLO
-       PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000033,
+       PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000000,
 #endif
 #if MEMORY_CONFIG == MEMORY_SUSE_SOLO
        PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000022,
@@ -1173,29 +1175,53 @@ static struct dimm_size spd_get_dimm_size(unsigned device)
        return sz;
 }
 
-static unsigned spd_to_dimm_side0(unsigned device)
+static unsigned spd_to_dimm(unsigned device)
 {
-       return (device - SMBUS_MEM_DEVICE_START) << 1;
+       return (device - SMBUS_MEM_DEVICE_START);
 }
 
-static unsigned spd_to_dimm_side1(unsigned device)
+static void set_dimm_size(struct dimm_size sz, unsigned index)
 {
-       return ((device - SMBUS_MEM_DEVICE_START) << 1) + 1;
-}
+       uint32_t base0, base1, map;
 
-static void set_dimm_size(unsigned long size, unsigned index)
-{
-       unsigned value = 0;
-       /* Make certain the dimm is at least 32MB */
-       if (size >= (25 + 3)) {
-               /* Place the dimm size in 32 MB quantities in the bits 31 - 21.
-                * The initialize dimm size is in bits.
-                * Set the base enable bit0.
-                */
-               value = (1 << ((size - (25 + 3)) + 21)) | 1;
+#if 1
+       print_debug("set_dimm_size: (");
+       print_debug_hex32(sz.side1);
+       print_debug_char(',');
+       print_debug_hex32(sz.side2);
+       print_debug_char(',');
+       print_debug_hex32(index);
+       print_debug(")\r\n");
+#endif
+       if (sz.side1 != sz.side2) {
+               sz.side2 = 0;
        }
+       map = pci_read_config32(PCI_DEV(0, 0x18, 2), 0x80);
+       map &= ~(0xf << (index + 4));
+
+       /* For each base register.
+        * Place the dimm size in 32 MB quantities in the bits 31 - 21.
+        * The initialize dimm size is in bits.
+        * Set the base enable bit0.
+        */
+       
+       base0 = base1 = 0;
+
+       /* Make certain side1 of the dimm is at least 32MB */
+       if (sz.side1 >= (25 + 3)) {
+               base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
+               map |= (sz.side1 - (25 + 3)) << (index *4);
+       }
+
+       /* Make certain side2 of the dimm is at least 32MB */
+       if (sz.side2 >= (25 + 3)) {
+               base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
+       }
+       
        /* Set the appropriate DIMM base address register */
-       pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (index << 2), value);
+       pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (((index << 1)+0)<<2), base0);
+       pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (((index << 1)+1)<<2), base1);
+       pci_write_config32(PCI_DEV(0, 0x18, 2), 0x80, map);
 }
 
 static void spd_set_ram_size(void)
@@ -1207,8 +1233,7 @@ static void spd_set_ram_size(void)
        {
                struct dimm_size sz;
                sz = spd_get_dimm_size(device);
-               set_dimm_size(sz.side1, spd_to_dimm_side0(device));
-               set_dimm_size(sz.side2, spd_to_dimm_side1(device));
+               set_dimm_size(sz, spd_to_dimm(device));
        }
 }
 
@@ -1235,14 +1260,12 @@ static void set_top_mem(unsigned tom_k)
 static void order_dimms(void)
 {
        unsigned long tom;
-       unsigned mask;
-       unsigned index;
 
        /* Remember which registers we have used in the high 8 bits of tom */
        tom = 0;
        for(;;) {
                /* Find the largest remaining canidate */
-               unsigned canidate;
+               unsigned index, canidate;
                uint32_t csbase, csmask;
                unsigned size;
                csbase = 0;
@@ -1292,12 +1315,17 @@ static void order_dimms(void)
 
                /* Write the new base register */
                pci_write_config32(PCI_DEV(0, 0x18, 2), 0x40 + (canidate << 2), csbase);
+               /* Write the new mask register */
                pci_write_config32(PCI_DEV(0, 0x18, 2), 0x60 + (canidate << 2), csmask);
                
        }
        set_top_mem((tom & ~0xff000000) << 15);
 }
 
+static void spd_set_dram_timing(void)
+{
+       
+}
 
 #define DRAM_CONFIG_LOW 0x90
 #define  DCL_DLL_Disable   (1<<0)
@@ -1322,6 +1350,7 @@ static void spd_set_ecc_mode(void)
 static void sdram_set_spd_registers(void) 
 {
        spd_set_ram_size();
+       spd_set_dram_timing();
        spd_set_ecc_mode();
        order_dimms();
 }
index 9722ca3fc7c7c375a2f1d1b842659d7bbc7f2e98..8df5ce1adcc576cef2e102dc6280bbe4e4967993 100644 (file)
@@ -1,12 +1,12 @@
-VERSION:=0.28
-RELEASE_DATE:=16 June 2003
+VERSION:=0.29
+RELEASE_DATE:=19 June 2003
 PACKAGE:=romcc
 
 
 # Move the configuration defines to makefile.conf
 CC=gcc
 CPPFLAGS=-DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(RELEASE_DATE)"'
-CFLAGS=-O -g -Wall $(CPPFLAGS)
+CFLAGS= -g -Wall $(CPPFLAGS)
 CPROF_FLAGS=-pg -fprofile-arcs
 
 all: romcc test
@@ -19,6 +19,7 @@ romcc_pg: romcc.c Makefile
 
 TESTS=\
        hello_world.c \
+       hello_world2.c \
        simple_test.c \
        simple_test2.c \
        simple_test3.c \
@@ -52,6 +53,10 @@ TESTS=\
        simple_test31.c \
        simple_test32.c \
        simple_test33.c \
+       simple_test34.c \
+       simple_test35.c \
+       simple_test36.c \
+       simple_test37.c \
        raminit_test.c \
        raminit_test2.c \
        raminit_test3.c \
index 24fe206b1b4f44c08415e727fb6c9864d325c97b..5c784fc5e67c94c2536713a0d26b36585798fb51 100644 (file)
@@ -215,6 +215,9 @@ struct file_state {
        char *pos;
        int line;
        char *line_start;
+       int report_line;
+       const char *report_name;
+       const char *report_dir;
 };
 struct hash_entry;
 struct token {
@@ -632,6 +635,14 @@ struct triple_set {
 #define MAX_MISC 15
 #define MAX_TARG 15
 
+struct occurance {
+       int count;
+       const char *filename;
+       const char *function;
+       int line;
+       int col;
+       struct occurance *parent;
+};
 struct triple {
        struct triple *next, *prev;
        struct triple_set *use;
@@ -665,9 +676,7 @@ struct triple {
 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
-       const char *filename;
-       int line;
-       int col;
+       struct occurance *occurance;
        union {
                ulong_t cval;
                struct block  *block;
@@ -744,6 +753,8 @@ struct compile_state {
        FILE *output;
        struct triple *vars;
        struct file_state *file;
+       struct occurance *last_occurance;
+       const char *function;
        struct token token[4];
        struct hash_entry *hash_table[HASH_TABLE_SIZE];
        struct hash_entry *i_continue;
@@ -956,7 +967,9 @@ static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
        int col;
        if (triple) {
                fprintf(fp, "%s:%d.%d: ", 
-                       triple->filename, triple->line, triple->col);
+                       triple->occurance->filename, 
+                       triple->occurance->line, 
+                       triple->occurance->col);
                return;
        }
        if (!state->file) {
@@ -964,7 +977,7 @@ static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
        }
        col = get_col(state->file);
        fprintf(fp, "%s:%d.%d: ", 
-               state->file->basename, state->file->line, col);
+               state->file->report_name, state->file->report_line, col);
 }
 
 static void __internal_error(struct compile_state *state, struct triple *ptr, 
@@ -1194,22 +1207,119 @@ static void pop_triple(struct triple *used, struct triple *unuser)
        }
 }
 
+static void put_occurance(struct occurance *occurance)
+{
+       occurance->count -= 1;
+       if (occurance->count <= 0) {
+               if (occurance->parent) {
+                       put_occurance(occurance->parent);
+               }
+               xfree(occurance);
+       }
+}
+
+static void get_occurance(struct occurance *occurance)
+{
+       occurance->count += 1;
+}
+
+
+static struct occurance *new_occurance(struct compile_state *state)
+{
+       struct occurance *result, *last;
+       const char *filename;
+       const char *function;
+       int line, col;
+
+       function = "";
+       filename = 0;
+       line = 0;
+       col  = 0;
+       if (state->file) {
+               filename = state->file->report_name;
+               line     = state->file->report_line;
+               col      = get_col(state->file);
+       }
+       if (state->function) {
+               function = state->function;
+       }
+       last = state->last_occurance;
+       if (last &&
+               (last->col == col) &&
+               (last->line == line) &&
+               (last->function == function) &&
+               (strcmp(last->filename, filename) == 0)) {
+               get_occurance(last);
+               return last;
+       }
+       if (last) {
+               state->last_occurance = 0;
+               put_occurance(last);
+       }
+       result = xmalloc(sizeof(*result), "occurance");
+       result->count    = 2;
+       result->filename = filename;
+       result->function = function;
+       result->line     = line;
+       result->col      = col;
+       result->parent   = 0;
+       state->last_occurance = result;
+       return result;
+}
+
+static struct occurance *inline_occurance(struct compile_state *state,
+       struct occurance *new, struct occurance *orig)
+{
+       struct occurance *result, *last;
+       last = state->last_occurance;
+       if (last &&
+               (last->parent   == orig) &&
+               (last->col      == new->col) &&
+               (last->line     == new->line) &&
+               (last->function == new->function) &&
+               (last->filename == new->filename)) {
+               get_occurance(last);
+               return last;
+       }
+       if (last) {
+               state->last_occurance = 0;
+               put_occurance(last);
+       }
+       get_occurance(orig);
+       result = xmalloc(sizeof(*result), "occurance");
+       result->count    = 2;
+       result->filename = new->filename;
+       result->function = new->function;
+       result->line     = new->line;
+       result->col      = new->col;
+       result->parent   = orig;
+       state->last_occurance = result;
+       return result;
+}
+       
+
+static struct occurance dummy_occurance = {
+       .count    = 2,
+       .filename = __FILE__,
+       .function = "",
+       .line     = __LINE__,
+       .col      = 0,
+       .parent   = 0,
+};
 
 /* The zero triple is used as a place holder when we are removing pointers
  * from a triple.  Having allows certain sanity checks to pass even
  * when the original triple that was pointed to is gone.
  */
 static struct triple zero_triple = {
-       .next     = &zero_triple,
-       .prev     = &zero_triple,
-       .use      = 0,
-       .op       = OP_INTCONST,
-       .sizes    = TRIPLE_SIZES(0, 0, 0, 0),
-       .id       = -1, /* An invalid id */
+       .next      = &zero_triple,
+       .prev      = &zero_triple,
+       .use       = 0,
+       .op        = OP_INTCONST,
+       .sizes     = TRIPLE_SIZES(0, 0, 0, 0),
+       .id        = -1, /* An invalid id */
        .u = { .cval   = 0, },
-       .filename = __FILE__,
-       .line     = __LINE__,
-       .col      = 0,
+       .occurance = &dummy_occurance,
        .param { [0] = 0, [1] = 0, },
 };
 
@@ -1268,7 +1378,7 @@ static unsigned short triple_sizes(struct compile_state *state,
 
 static struct triple *alloc_triple(struct compile_state *state, 
        int op, struct type *type, int lhs, int rhs,
-       const char *filename, int line, int col)
+       struct occurance *occurance)
 {
        size_t size, sizes, extra_count, min_count;
        struct triple *ret;
@@ -1280,14 +1390,12 @@ static struct triple *alloc_triple(struct compile_state *state,
 
        size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
        ret = xcmalloc(size, "tripple");
-       ret->op       = op;
-       ret->sizes    = sizes;
-       ret->type     = type;
-       ret->next     = ret;
-       ret->prev     = ret;
-       ret->filename = filename;
-       ret->line     = line;
-       ret->col      = col;
+       ret->op        = op;
+       ret->sizes     = sizes;
+       ret->type      = type;
+       ret->next      = ret;
+       ret->prev      = ret;
+       ret->occurance = occurance;
        return ret;
 }
 
@@ -1298,8 +1406,9 @@ struct triple *dup_triple(struct compile_state *state, struct triple *src)
        src_lhs = TRIPLE_LHS(src->sizes);
        src_rhs = TRIPLE_RHS(src->sizes);
        src_size = TRIPLE_SIZE(src->sizes);
+       get_occurance(src->occurance);
        dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
-               src->filename, src->line, src->col);
+               src->occurance);
        memcpy(dup, src, sizeof(*src));
        memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
        return dup;
@@ -1309,28 +1418,19 @@ static struct triple *new_triple(struct compile_state *state,
        int op, struct type *type, int lhs, int rhs)
 {
        struct triple *ret;
-       const char *filename;
-       int line, col;
-       filename = 0;
-       line = 0;
-       col  = 0;
-       if (state->file) {
-               filename = state->file->basename;
-               line     = state->file->line;
-               col      = get_col(state->file);
-       }
-       ret = alloc_triple(state, op, type, lhs, rhs,
-               filename, line, col);
+       struct occurance *occurance;
+       occurance = new_occurance(state);
+       ret = alloc_triple(state, op, type, lhs, rhs, occurance);
        return ret;
 }
 
 static struct triple *build_triple(struct compile_state *state, 
        int op, struct type *type, struct triple *left, struct triple *right,
-       const char *filename, int line, int col)
+       struct occurance *occurance)
 {
        struct triple *ret;
        size_t count;
-       ret = alloc_triple(state, op, type, -1, -1, filename, line, col);
+       ret = alloc_triple(state, op, type, -1, -1, occurance);
        count = TRIPLE_SIZE(ret->sizes);
        if (count > 0) {
                ret->param[0] = left;
@@ -1433,8 +1533,8 @@ static struct triple *pre_triple(struct compile_state *state,
                base = MISC(base, 0);
        }
        block = block_of_triple(state, base);
-       ret = build_triple(state, op, type, left, right, 
-               base->filename, base->line, base->col);
+       get_occurance(base->occurance);
+       ret = build_triple(state, op, type, left, right, base->occurance);
        if (triple_stores_block(state, ret)) {
                ret->u.block = block;
        }
@@ -1463,8 +1563,8 @@ static struct triple *post_triple(struct compile_state *state,
        }
 
        block = block_of_triple(state, base);
-       ret = build_triple(state, op, type, left, right, 
-               base->filename, base->line, base->col);
+       get_occurance(base->occurance);
+       ret = build_triple(state, op, type, left, right, base->occurance);
        if (triple_stores_block(state, ret)) {
                ret->u.block = block;
        }
@@ -1485,22 +1585,31 @@ static struct triple *label(struct compile_state *state)
 
 static void display_triple(FILE *fp, struct triple *ins)
 {
+       struct occurance *ptr;
+       const char *reg;
+       char pre, post;
+       pre = post = ' ';
+       if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
+               pre = '^';
+       }
+       if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
+               post = 'v';
+       }
+       reg = arch_reg_str(ID_REG(ins->id));
        if (ins->op == OP_INTCONST) {
-               fprintf(fp, "(%p) %3d %-2d %-10s <0x%08lx>          @ %s:%d.%d\n",
-                       ins, ID_REG(ins->id), ins->template_id, tops(ins->op), 
-                       ins->u.cval,
-                       ins->filename, ins->line, ins->col);
+               fprintf(fp, "(%p) %c%c %-7s %-2d %-10s <0x%08lx>         ",
+                       ins, pre, post, reg, ins->template_id, tops(ins->op), 
+                       ins->u.cval);
        }
        else if (ins->op == OP_ADDRCONST) {
-               fprintf(fp, "(%p) %3d %-2d %-10s %-10p <0x%08lx> @ %s:%d.%d\n",
-                       ins, ID_REG(ins->id), ins->template_id, tops(ins->op), 
-                       MISC(ins, 0), ins->u.cval,
-                       ins->filename, ins->line, ins->col);
+               fprintf(fp, "(%p) %c%c %-7s %-2d %-10s %-10p <0x%08lx>",
+                       ins, pre, post, reg, ins->template_id, tops(ins->op), 
+                       MISC(ins, 0), ins->u.cval);
        }
        else {
                int i, count;
-               fprintf(fp, "(%p) %3d %-2d %-10s", 
-                       ins, ID_REG(ins->id), ins->template_id, tops(ins->op));
+               fprintf(fp, "(%p) %c%c %-7s %-2d %-10s", 
+                       ins, pre, post, reg, ins->template_id, tops(ins->op));
                count = TRIPLE_SIZE(ins->sizes);
                for(i = 0; i < count; i++) {
                        fprintf(fp, " %-10p", ins->param[i]);
@@ -1508,9 +1617,16 @@ static void display_triple(FILE *fp, struct triple *ins)
                for(; i < 2; i++) {
                        fprintf(fp, "           ");
                }
-               fprintf(fp, " @ %s:%d.%d\n", 
-                       ins->filename, ins->line, ins->col);
        }
+       fprintf(fp, " @");
+       for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
+               fprintf(fp, " %s,%s:%d.%d",
+                       ptr->function, 
+                       ptr->filename,
+                       ptr->line, 
+                       ptr->col);
+       }
+       fprintf(fp, "\n");
        fflush(fp);
 }
 
@@ -1662,6 +1778,7 @@ static void free_triple(struct compile_state *state, struct triple *ptr)
        if (ptr->use) {
                internal_error(state, ptr, "ptr->use != 0");
        }
+       put_occurance(ptr->occurance);
        memset(ptr, -1, size);
        xfree(ptr);
 }
@@ -2383,6 +2500,7 @@ next_token:
                while ((tokp < end) && spacep(c)) {
                        if (c == '\n') {
                                file->line++;
+                               file->report_line++;
                                file->line_start = tokp + 1;
                        }
                        c = *(++tokp);
@@ -2398,6 +2516,7 @@ next_token:
                        c = *tokp;
                        if (c == '\n') {
                                file->line++;
+                               file->report_line++;
                                file->line_start = tokp +1;
                                break;
                        }
@@ -2424,6 +2543,7 @@ next_token:
                if (tok == TOK_UNKNOWN) {
                        error(state, 0, "unterminated comment");
                }
+               file->report_line += line - file->line;
                file->line = line;
                file->line_start = line_start;
        }
@@ -2460,6 +2580,7 @@ next_token:
                if (line != file->line) {
                        warning(state, 0, "multiline string constant");
                }
+               file->report_line += line - file->line;
                file->line = line;
                file->line_start = line_start;
 
@@ -2499,6 +2620,7 @@ next_token:
                if (line != file->line) {
                        warning(state, 0, "multiline character constant");
                }
+               file->report_line += line - file->line;
                file->line = line;
                file->line_start = line_start;
 
@@ -2698,6 +2820,9 @@ static void compile_macro(struct compile_state *state, struct token *tk)
        file->pos = file->buf;
        file->line_start = file->pos;
        file->line = 1;
+       file->report_line = 1;
+       file->report_name = file->basename;
+       file->report_dir  = file->dirname;
        file->prev = state->file;
        state->file = file;
 }
@@ -2719,6 +2844,9 @@ static int mpeek(struct compile_state *state, int index)
                        struct file_state *file = state->file;
                        state->file = file->prev;
                        /* file->basename is used keep it */
+                       if (file->report_dir != file->dirname) {
+                               xfree(file->report_dir);
+                       }
                        xfree(file->dirname);
                        xfree(file->buf);
                        xfree(file);
@@ -3078,8 +3206,69 @@ static void preprocess(struct compile_state *state, int index)
                        tk->ident->name);
        }
        switch(tk->tok) {
-       case TOK_UNDEF:
+       case TOK_LIT_INT:
+       {
+               int override_line;
+               override_line = strtoul(tk->val.str, 0, 10);
+               next_token(state, index);
+               /* I have a cpp line marker parse it */
+               if (tk->tok == TOK_LIT_STRING) {
+                       const char *token, *base;
+                       char *name, *dir;
+                       int name_len, dir_len;
+                       name = xmalloc(tk->str_len, "report_name");
+                       token = tk->val.str + 1;
+                       base = strrchr(token, '/');
+                       name_len = tk->str_len -2;
+                       if (base != 0) {
+                               dir_len = base - token;
+                               base++;
+                               name_len -= base - token;
+                       } else {
+                               dir_len = 0;
+                               base = token;
+                       }
+                       memcpy(name, base, name_len);
+                       name[name_len] = '\0';
+                       dir = xmalloc(dir_len + 1, "report_dir");
+                       memcpy(dir, token, dir_len);
+                       dir[dir_len] = '\0';
+                       file->report_line = override_line - 1;
+                       file->report_name = name;
+                       file->report_dir = dir;
+               }
+       }
+               break;
        case TOK_LINE:
+               meat(state, index, TOK_LINE);
+               meat(state, index, TOK_LIT_INT);
+               file->report_line = strtoul(tk->val.str, 0, 10) -1;
+               if (mpeek(state, index) == TOK_LIT_STRING) {
+                       const char *token, *base;
+                       char *name, *dir;
+                       int name_len, dir_len;
+                       meat(state, index, TOK_LIT_STRING);
+                       name = xmalloc(tk->str_len, "report_name");
+                       token = tk->val.str + 1;
+                       name_len = tk->str_len - 2;
+                       if (base != 0) {
+                               dir_len = base - token;
+                               base++;
+                               name_len -= base - token;
+                       } else {
+                               dir_len = 0;
+                               base = token;
+                       }
+                       memcpy(name, base, name_len);
+                       name[name_len] = '\0';
+                       dir = xmalloc(dir_len + 1, "report_dir");
+                       memcpy(dir, token, dir_len);
+                       dir[dir_len] = '\0';
+                       file->report_name = name;
+                       file->report_dir = dir;
+               }
+               break;
+       case TOK_UNDEF:
        case TOK_PRAGMA:
                if (state->if_value < 0) {
                        break;
@@ -3476,6 +3665,10 @@ static void compile_file(struct compile_state *state, const char *filename, int
        file->line_start = file->pos;
        file->line = 1;
 
+       file->report_line = 1;
+       file->report_name = file->basename;
+       file->report_dir  = file->dirname;
+
        file->prev = state->file;
        state->file = file;
        
@@ -4725,7 +4918,8 @@ static struct triple *flatten_cond(
        return read_expr(state, val);
 }
 
-struct triple *copy_func(struct compile_state *state, struct triple *ofunc)
+struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
+       struct occurance *base_occurance)
 {
        struct triple *nfunc;
        struct triple *nfirst, *ofirst;
@@ -4745,11 +4939,13 @@ struct triple *copy_func(struct compile_state *state, struct triple *ofunc)
        ofirst = old = RHS(ofunc, 0);
        do {
                struct triple *new;
+               struct occurance *occurance;
                int old_lhs, old_rhs;
                old_lhs = TRIPLE_LHS(old->sizes);
                old_rhs = TRIPLE_RHS(old->sizes);
+               occurance = inline_occurance(state, base_occurance, old->occurance);
                new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
-                       old->filename, old->line, old->col);
+                       occurance);
                if (!triple_stores_block(state, new)) {
                        memcpy(&new->u, &old->u, sizeof(new->u));
                }
@@ -4822,7 +5018,7 @@ static struct triple *flatten_call(
        if (ofunc->op != OP_LIST) {
                internal_error(state, 0, "improper function");
        }
-       nfunc = copy_func(state, ofunc);
+       nfunc = copy_func(state, ofunc, ptr->occurance);
        nfirst = RHS(nfunc, 0)->next;
        /* Prepend the parameter reading into the new function list */
        ptype = nfunc->type->right;
@@ -5410,8 +5606,9 @@ static void flatten_structures(struct compile_state *state)
 
                                op = ins->op;
                                def = RHS(ins, 0);
+                               get_occurance(ins->occurance);
                                next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
-                                       ins->filename, ins->line, ins->col);
+                                       ins->occurance);
 
                                vector = &RHS(next, 0);
                                tptr = next->type->left;
@@ -5426,9 +5623,9 @@ static void flatten_structures(struct compile_state *state)
                                        
                                        vector[i] = triple(
                                                state, op, mtype, sfield, 0);
-                                       vector[i]->filename = next->filename;
-                                       vector[i]->line = next->line;
-                                       vector[i]->col = next->col;
+                                       put_occurance(vector[i]->occurance);
+                                       get_occurance(next->occurance);
+                                       vector[i]->occurance = next->occurance;
                                        tptr = tptr->right;
                                }
                                propogate_use(state, ins, next);
@@ -5444,8 +5641,9 @@ static void flatten_structures(struct compile_state *state)
                                op = ins->op;
                                src = RHS(ins, 0);
                                dst = LHS(ins, 0);
+                               get_occurance(ins->occurance);
                                next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
-                                       ins->filename, ins->line, ins->col);
+                                       ins->occurance);
                                
                                vector = &RHS(next, 0);
                                tptr = next->type->left;
@@ -5460,9 +5658,9 @@ static void flatten_structures(struct compile_state *state)
                                        dfield = deref_field(state, dst, mtype->field_ident);
                                        vector[i] = triple(
                                                state, op, mtype, dfield, sfield);
-                                       vector[i]->filename = next->filename;
-                                       vector[i]->line = next->line;
-                                       vector[i]->col = next->col;
+                                       put_occurance(vector[i]->occurance);
+                                       get_occurance(next->occurance);
+                                       vector[i]->occurance = next->occurance;
                                        tptr = tptr->right;
                                }
                                propogate_use(state, ins, next);
@@ -6344,10 +6542,13 @@ static void register_builtin_function(struct compile_state *state,
 
        /* Dummy file state to get debug handling right */
        memset(&file, 0, sizeof(file));
-       file.basename = name;
+       file.basename = "<built-in>";
        file.line = 1;
+       file.report_line = 1;
+       file.report_name = file.basename;
        file.prev = state->file;
        state->file = &file;
+       state->function = name;
 
        /* Find the Parameter count */
        valid_op(state, op);
@@ -6436,6 +6637,7 @@ static void register_builtin_function(struct compile_state *state,
        symbol(state, ident, &ident->sym_ident, def, ftype);
        
        state->file = file.prev;
+       state->function = 0;
 #if 0
        fprintf(stdout, "\n");
        loc(stdout, state, 0);
@@ -8790,8 +8992,10 @@ static void decl(struct compile_state *state, struct triple *first)
        type = declarator(state, base_type, &ident, 0);
        if (global && ident && (peek(state) == TOK_LBRACE)) {
                /* function */
+               state->function = ident->name;
                def = function_definition(state, type);
                symbol(state, ident, &ident->sym_ident, def, type);
+               state->function = 0;
        }
        else {
                int done;
@@ -9962,11 +10166,10 @@ static void insert_phi_operations(struct compile_state *state)
                                /* Count how many edges flow into this block */
                                in_edges = front->users;
                                /* Insert a phi function for this variable */
+                               get_occurance(front->first->occurance);
                                phi = alloc_triple(
                                        state, OP_PHI, var->type, -1, in_edges, 
-                                       front->first->filename, 
-                                       front->first->line,
-                                       front->first->col);
+                                       front->first->occurance);
                                phi->u.block = front;
                                MISC(phi, 0) = var;
                                use_triple(var, phi);
@@ -10624,8 +10827,9 @@ static void insert_copies_to_phi(struct compile_state *state)
                                continue;
                        }
 
+                       get_occurance(val->occurance);
                        move = build_triple(state, OP_COPY, phi->type, val, 0,
-                               val->filename, val->line, val->col);
+                               val->occurance);
                        move->u.block = eblock;
                        move->id |= TRIPLE_FLAG_PRE_SPLIT;
                        use_triple(val, move);
@@ -11266,6 +11470,7 @@ static void insert_mandatory_copies(struct compile_state *state)
                                                        internal_error(state, user, "bad rhs");
                                                }
                                                tmp = pre_copy(state, user, i);
+                                               tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
                                                continue;
                                        } else {
                                                do_post_copy = 1;
@@ -11281,6 +11486,7 @@ static void insert_mandatory_copies(struct compile_state *state)
                                                internal_error(state, user, "bad rhs");
                                        }
                                        tmp = pre_copy(state, user, i);
+                                       tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
                                        continue;
                                } else {
                                        do_post_copy = 1;
@@ -11292,6 +11498,7 @@ static void insert_mandatory_copies(struct compile_state *state)
                if (do_post_copy) {
                        struct reg_info pre, post;
                        tmp = post_copy(state, ins);
+                       tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
                        pre = arch_reg_lhs(state, ins, 0);
                        post = arch_reg_lhs(state, tmp, 0);
                        if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
@@ -11457,7 +11664,10 @@ static struct lre_hash **lre_probe(struct reg_state *rstate,
        index = hash_live_edge(left, right);
        
        ptr = &rstate->hash[index];
-       while((*ptr) && ((*ptr)->left != left) && ((*ptr)->right != right)) {
+       while(*ptr) {
+               if (((*ptr)->left == left) && ((*ptr)->right == right)) {
+                       break;
+               }
                ptr = &(*ptr)->next;
        }
        return ptr;
@@ -11495,6 +11705,10 @@ static void add_live_edge(struct reg_state *rstate,
        if (*ptr) {
                return;
        }
+#if 0
+       fprintf(stderr, "new_live_edge(%p, %p)\n",
+               left, right);
+#endif
        new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
        new_hash->next  = *ptr;
        new_hash->left  = left;
@@ -11533,6 +11747,7 @@ static void remove_live_edge(struct reg_state *rstate,
                        *ptr = edge->next;
                        memset(edge, 0, sizeof(*edge));
                        xfree(edge);
+                       right->degree--;
                        break;
                }
        }
@@ -11542,6 +11757,7 @@ static void remove_live_edge(struct reg_state *rstate,
                        *ptr = edge->next;
                        memset(edge, 0, sizeof(*edge));
                        xfree(edge);
+                       left->degree--;
                        break;
                }
        }
@@ -11671,7 +11887,7 @@ static struct live_range *coalesce_ranges(
                fprintf(stderr, "lr2 pre\n");
        }
 #endif
-#if 0
+#if 1
        fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
                lr1->defs->def,
                lr1->color,
@@ -11894,6 +12110,85 @@ static void graph_ins(
        return;
 }
 
+static struct live_range *get_verify_live_range(
+       struct compile_state *state, struct reg_state *rstate, struct triple *ins)
+{
+       struct live_range *lr;
+       struct live_range_def *lrd;
+       int ins_found;
+       if ((ins->id < 0) || (ins->id > rstate->defs)) {
+               internal_error(state, ins, "bad ins?");
+       }
+       lr = rstate->lrd[ins->id].lr;
+       ins_found = 0;
+       lrd = lr->defs;
+       do {
+               if (lrd->def == ins) {
+                       ins_found = 1;
+               }
+               lrd = lrd->next;
+       } while(lrd != lr->defs);
+       if (!ins_found) {
+               internal_error(state, ins, "ins not in live range");
+       }
+       return lr;
+}
+
+static void verify_graph_ins(
+       struct compile_state *state, 
+       struct reg_block *blocks, struct triple_reg_set *live, 
+       struct reg_block *rb, struct triple *ins, void *arg)
+{
+       struct reg_state *rstate = arg;
+       struct triple_reg_set *entry1, *entry2;
+
+
+       /* Compare live against edges and make certain the code is working */
+       for(entry1 = live; entry1; entry1 = entry1->next) {
+               struct live_range *lr1;
+               lr1 = get_verify_live_range(state, rstate, entry1->member);
+               for(entry2 = live; entry2; entry2 = entry2->next) {
+                       struct live_range *lr2;
+                       struct live_range_edge *edge2;
+                       int lr1_found;
+                       int lr2_degree;
+                       if (entry2 == entry1) {
+                               continue;
+                       }
+                       lr2 = get_verify_live_range(state, rstate, entry2->member);
+                       if (lr1 == lr2) {
+                               internal_error(state, entry2->member, 
+                                       "live range with 2 values simultaneously alive");
+                       }
+                       if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
+                               continue;
+                       }
+                       if (!interfere(rstate, lr1, lr2)) {
+                               internal_error(state, entry2->member, 
+                                       "edges don't interfere?");
+                       }
+                               
+                       lr1_found = 0;
+                       lr2_degree = 0;
+                       for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
+                               lr2_degree++;
+                               if (edge2->node == lr1) {
+                                       lr1_found = 1;
+                               }
+                       }
+                       if (lr2_degree != lr2->degree) {
+                               internal_error(state, entry2->member,
+                                       "computed degree: %d does not match reported degree: %d\n",
+                                       lr2_degree, lr2->degree);
+                       }
+                       if (!lr1_found) {
+                               internal_error(state, entry2->member, "missing edge");
+                       }
+               }
+       }
+       return;
+}
+
 
 static void print_interference_ins(
        struct compile_state *state, 
@@ -11902,9 +12197,14 @@ static void print_interference_ins(
 {
        struct reg_state *rstate = arg;
        struct live_range *lr;
+       unsigned id;
 
        lr = rstate->lrd[ins->id].lr;
+       id = ins->id;
+       ins->id = rstate->lrd[id].orig_id;
+       SET_REG(ins->id, lr->color);
        display_triple(stdout, ins);
+       ins->id = id;
 
        if (lr->defs) {
                struct live_range_def *lrd;
@@ -12033,7 +12333,7 @@ static int coalesce_live_ranges(
                                if (interfere(rstate, lr1, lr2)) {
                                        continue;
                                }
-                               
+
                                res = coalesce_ranges(state, rstate, lr1, lr2);
                                coalesced += 1;
                                if (res != lr1) {
@@ -13066,6 +13366,7 @@ static void print_interference_block(
                        }
                }
                id = ptr->id;
+               ptr->id = rstate->lrd[id].orig_id;
                SET_REG(ptr->id, lr->color);
                display_triple(stdout, ptr);
                ptr->id = id;
@@ -13278,6 +13579,9 @@ static void allocate_registers(struct compile_state *state)
                        /* Forget previous live range edge calculations */
                        cleanup_live_edges(&rstate);
 
+#if 0
+                       fprintf(stderr, "coalescing\n");
+#endif                 
                        /* Compute the interference graph */
                        walk_variable_lifetimes(
                                state, rstate.blocks, graph_ins, &rstate);
@@ -13291,6 +13595,11 @@ static void allocate_registers(struct compile_state *state)
                                        state, rstate.blocks, 
                                        print_interference_ins, &rstate);
                        }
+#if DEBUG_CONSISTENCY
+                       /* Verify the interference graph */
+                       walk_variable_lifetimes(
+                               state, rstate.blocks, verify_graph_ins, &rstate);
+#endif
                        
                        coalesced = coalesce_live_ranges(state, &rstate);
                } while(coalesced);
@@ -15745,8 +16054,8 @@ static int check_reg(struct compile_state *state,
 static const char *arch_reg_str(int reg)
 {
        static const char *regs[] = {
-               "%bad_register",
-               "%bad_register2",
+               "%unset",
+               "%unneeded",
                "%eflags",
                "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
                "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
@@ -16487,28 +16796,42 @@ static void print_instructions(struct compile_state *state)
 {
        struct triple *first, *ins;
        int print_location;
-       int last_line;
-       int last_col;
-       const char *last_filename;
+       struct occurance *last_occurance;
        FILE *fp;
        print_location = 1;
-       last_line = -1;
-       last_col  = -1;
-       last_filename = 0;
+       last_occurance = 0;
        fp = state->output;
        fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
        first = RHS(state->main_function, 0);
        ins = first;
        do {
-               if (print_location &&
-                       ((last_filename != ins->filename) ||
-                               (last_line != ins->line) ||
-                               (last_col  != ins->col))) {
-                       fprintf(fp, "\t/* %s:%d */\n",
-                               ins->filename, ins->line);
-                       last_filename = ins->filename;
-                       last_line = ins->line;
-                       last_col  = ins->col;
+               if (print_location && 
+                       last_occurance != ins->occurance) {
+                       if (!ins->occurance->parent) {
+                               fprintf(fp, "\t/* %s,%s:%d.%d */\n",
+                                       ins->occurance->function,
+                                       ins->occurance->filename,
+                                       ins->occurance->line,
+                                       ins->occurance->col);
+                       }
+                       else {
+                               struct occurance *ptr;
+                               fprintf(fp, "\t/*\n");
+                               for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
+                                       fprintf(fp, "\t * %s,%s:%d.%d\n",
+                                               ptr->function,
+                                               ptr->filename,
+                                               ptr->line,
+                                               ptr->col);
+                               }
+                               fprintf(fp, "\t */\n");
+                               
+                       }
+                       if (last_occurance) {
+                               put_occurance(last_occurance);
+                       }
+                       get_occurance(ins->occurance);
+                       last_occurance = ins->occurance;
                }
 
                print_instruction(state, ins, fp);
diff --git a/util/romcc/tests/simple_test34.c b/util/romcc/tests/simple_test34.c
new file mode 100644 (file)
index 0000000..3c2b606
--- /dev/null
@@ -0,0 +1,71 @@
+
+typedef __builtin_msr_t msr_t;
+
+static msr_t rdmsr(unsigned long index)
+{
+        return __builtin_rdmsr(index);
+}
+
+static void uart_tx_byte(unsigned char data)
+{
+       while(!(__builtin_inb(0x3f8 + 0x05) & 0x20))
+               ;
+        __builtin_outb(data, 0x3f8 + 0x00);
+
+        while(!(__builtin_inb(0x3f8 + 0x05) & 0x40))
+                ;
+}
+
+
+static void print_nibble(unsigned nibble)
+{
+       unsigned char digit;
+       digit = nibble + '0';
+       if (digit > '9') {
+               digit += 39;
+       }
+       uart_tx_byte(digit);
+}
+
+static void print_debug_hex32(unsigned int value)
+{
+       print_nibble((value >> 28U) & 0x0fU);
+       print_nibble((value >> 24U) & 0x0fU);
+       print_nibble((value >> 20U) & 0x0fU);
+       print_nibble((value >> 16U) & 0x0fU);
+       print_nibble((value >> 12U) & 0x0fU);
+       print_nibble((value >> 8U) & 0x0fU);
+       print_nibble((value >> 4U) & 0x0fU);
+       print_nibble(value & 0x0fU);
+}
+
+static void print_debug(const char *str)
+{
+       unsigned char ch;
+       while((ch = *str++) != '\0') {
+               uart_tx_byte(ch);
+       }
+}
+
+static void main(void)
+{
+       unsigned long start, stop;
+       msr_t msr;
+       msr = rdmsr(0xC001001A);
+       print_debug("TOP_MEM: ");
+       print_debug_hex32(msr.hi);
+       print_debug_hex32(msr.lo);
+       print_debug("\r\n");
+
+       start = 0;
+       stop = msr.lo;
+        print_debug("Testing DRAM : ");
+        print_debug_hex32(start);
+        print_debug("-");
+        print_debug_hex32(stop);
+        print_debug("\r\n");
+
+        print_debug("DRAM verify: ");
+        print_debug_hex32(start);
+        print_debug_hex32(stop);
+}
diff --git a/util/romcc/tests/simple_test35.c b/util/romcc/tests/simple_test35.c
new file mode 100644 (file)
index 0000000..d60b157
--- /dev/null
@@ -0,0 +1,9 @@
+static void main(void)
+{
+       __builtin_msr_t msr;
+       msr = __builtin_rdmsr(0xC001001A);
+       while(__builtin_inb(0x3fd))
+               ;
+        __builtin_outb(msr.hi, 0x3f8);
+
+}
diff --git a/util/romcc/tests/simple_test36.c b/util/romcc/tests/simple_test36.c
new file mode 100644 (file)
index 0000000..9044bda
--- /dev/null
@@ -0,0 +1,41 @@
+static void order_dimms(void)
+{
+        unsigned long tom;
+
+        tom = 0;
+        for(;;) {
+
+                unsigned csbase, csmask;
+                unsigned size;
+               unsigned index;
+                csbase = 0;
+
+                for(index = 0; index < 1; index++) {
+                       csbase = __builtin_inl(0x40);
+                }
+                if (csbase == 0) {
+                        break;
+                }
+
+
+                size = csbase;
+
+                csbase = (tom << 21);
+
+                tom += size;
+
+
+                csmask = size;
+                csmask |= 0xfe00;
+
+
+               __builtin_outl(csbase, 0xCFC);
+
+               __builtin_outl(0xc260, 0xCF8);
+               __builtin_outl(csmask, 0xCFC);
+        }
+       
+       tom &=  ~0xff000000;
+
+       __builtin_outl(tom, 0x1234);
+}
diff --git a/util/romcc/tests/simple_test37.c b/util/romcc/tests/simple_test37.c
new file mode 100644 (file)
index 0000000..85c622b
--- /dev/null
@@ -0,0 +1,10 @@
+static void main(void)
+{
+       unsigned csbase, csmask;
+
+       csbase = 0x40;
+       csmask = 0xfe00;
+       
+       __builtin_outl(csbase, 0x40);
+       __builtin_outl(csmask, 0x60);
+}