summaryrefslogtreecommitdiff
path: root/util/romcc
diff options
context:
space:
mode:
Diffstat (limited to 'util/romcc')
-rw-r--r--util/romcc/Makefile11
-rw-r--r--util/romcc/romcc.c505
-rw-r--r--util/romcc/tests/simple_test34.c71
-rw-r--r--util/romcc/tests/simple_test35.c9
-rw-r--r--util/romcc/tests/simple_test36.c41
-rw-r--r--util/romcc/tests/simple_test37.c10
6 files changed, 553 insertions, 94 deletions
diff --git a/util/romcc/Makefile b/util/romcc/Makefile
index 9722ca3fc7..8df5ce1adc 100644
--- a/util/romcc/Makefile
+++ b/util/romcc/Makefile
@@ -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 \
diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c
index 24fe206b1b..5c784fc5e6 100644
--- a/util/romcc/romcc.c
+++ b/util/romcc/romcc.c
@@ -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
index 0000000000..3c2b606fc2
--- /dev/null
+++ b/util/romcc/tests/simple_test34.c
@@ -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
index 0000000000..d60b157f25
--- /dev/null
+++ b/util/romcc/tests/simple_test35.c
@@ -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
index 0000000000..9044bda7b9
--- /dev/null
+++ b/util/romcc/tests/simple_test36.c
@@ -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
index 0000000000..85c622b17d
--- /dev/null
+++ b/util/romcc/tests/simple_test37.c
@@ -0,0 +1,10 @@
+static void main(void)
+{
+ unsigned csbase, csmask;
+
+ csbase = 0x40;
+ csmask = 0xfe00;
+
+ __builtin_outl(csbase, 0x40);
+ __builtin_outl(csmask, 0x60);
+}