Commit 9fcd5f66 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Allow two should-be-same constraints for every out register. This is useful...

Allow two should-be-same constraints for every out register. This is useful for commutative nodes on two address code machines (i.e. x86).

[r15953]
parent 8a45e869
...@@ -91,7 +91,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, ...@@ -91,7 +91,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
} }
if (reqs[i]->type & arch_register_req_type_should_be_same) { if (reqs[i]->type & arch_register_req_type_should_be_same) {
ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same)); ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same[0]));
if (reqs[i]->other_same[1] != -1)
ir_fprintf(F, " or %+F", get_irn_n(n, reqs[i]->other_same[1]));
} }
if (reqs[i]->type & arch_register_req_type_should_be_different) { if (reqs[i]->type & arch_register_req_type_should_be_different) {
......
...@@ -100,7 +100,9 @@ static void dump_reg_req(FILE *F, const ir_node *node, ...@@ -100,7 +100,9 @@ static void dump_reg_req(FILE *F, const ir_node *node,
} }
if (reqs[i]->type & arch_register_req_type_should_be_same) { if (reqs[i]->type & arch_register_req_type_should_be_same) {
ir_fprintf(F, " same as %+F", get_irn_n(node, reqs[i]->other_same)); ir_fprintf(F, " same as %+F", get_irn_n(node, reqs[i]->other_same[0]));
if (reqs[i]->other_same[1] != -1)
ir_fprintf(F, " or %+F", get_irn_n(node, reqs[i]->other_same[1]));
} }
if (reqs[i]->type & arch_register_req_type_should_be_different) { if (reqs[i]->type & arch_register_req_type_should_be_different) {
......
...@@ -333,9 +333,14 @@ extern char *arch_register_req_format(char *buf, size_t len, ...@@ -333,9 +333,14 @@ extern char *arch_register_req_format(char *buf, size_t len,
} }
if(arch_register_req_is(req, should_be_same)) { if(arch_register_req_is(req, should_be_same)) {
const ir_node *same = get_irn_n(skip_Proj_const(node), req->other_same); const ir_node *same = get_irn_n(skip_Proj_const(node), req->other_same[0]);
ir_snprintf(tmp, sizeof(tmp), " same to: %+F", same); ir_snprintf(tmp, sizeof(tmp), " same to: %+F", same);
strncat(buf, tmp, len); strncat(buf, tmp, len);
if (req->other_same[1] != -1) {
const ir_node *same2 = get_irn_n(skip_Proj_const(node), req->other_same[1]);
ir_snprintf(tmp, sizeof(tmp), "or %+F", same2);
strncat(buf, tmp, len);
}
} }
if(arch_register_req_is(req, should_be_different)) { if(arch_register_req_is(req, should_be_different)) {
......
...@@ -128,8 +128,11 @@ struct arch_register_req_t { ...@@ -128,8 +128,11 @@ struct arch_register_req_t {
const unsigned *limited; /**< allowed register bitset */ const unsigned *limited; /**< allowed register bitset */
int other_same; /**< The in number which shall have int other_same[2]; /**< The in numbers which shall have the
the same res (should_be_same)*/ same res (should_be_same). More than
two are unnecessary because there is
no machine with more than two
commutative inputs to one operation */
int other_different; /**< The other node from which this int other_different; /**< The other node from which this
one's register must be different one's register must be different
(case must_be_different). */ (case must_be_different). */
......
...@@ -462,7 +462,7 @@ static void co_collect_units(ir_node *irn, void *env) { ...@@ -462,7 +462,7 @@ static void co_collect_units(ir_node *irn, void *env) {
/* Src == Tgt of a 2-addr-code instruction */ /* Src == Tgt of a 2-addr-code instruction */
if (is_2addr_code(req)) { if (is_2addr_code(req)) {
ir_node *other = get_irn_n(skip_Proj(irn), req->other_same); ir_node *other = get_irn_n(skip_Proj(irn), req->other_same[0]); /* TODO handle second should-be-same constraint */
if (!arch_irn_is(co->aenv, other, ignore) && if (!arch_irn_is(co->aenv, other, ignore) &&
!nodes_interfere(co->cenv, irn, other)) { !nodes_interfere(co->cenv, irn, other)) {
unit->nodes = xmalloc(2 * sizeof(*unit->nodes)); unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
...@@ -765,27 +765,29 @@ static void build_graph_walker(ir_node *irn, void *env) { ...@@ -765,27 +765,29 @@ static void build_graph_walker(ir_node *irn, void *env) {
if (arch_register_type_is(reg, ignore)) if (arch_register_type_is(reg, ignore))
return; return;
/* Phis */ if (is_Reg_Phi(irn)) { /* Phis */
if (is_Reg_Phi(irn))
for (pos=0, max=get_irn_arity(irn); pos<max; ++pos) { for (pos=0, max=get_irn_arity(irn); pos<max; ++pos) {
ir_node *arg = get_irn_n(irn, pos); ir_node *arg = get_irn_n(irn, pos);
add_edges(co, irn, arg, co->get_costs(co, irn, arg, pos)); add_edges(co, irn, arg, co->get_costs(co, irn, arg, pos));
} }
}
/* Perms */ else if (is_Perm_Proj(co->aenv, irn)) { /* Perms */
else if (is_Perm_Proj(co->aenv, irn)) {
ir_node *arg = get_Perm_src(irn); ir_node *arg = get_Perm_src(irn);
add_edges(co, irn, arg, co->get_costs(co, irn, arg, 0)); add_edges(co, irn, arg, co->get_costs(co, irn, arg, 0));
} }
else { /* 2-address code */
/* 2-address code */ const arch_register_req_t *req = arch_get_register_req(co->aenv, irn, -1);
else {
const arch_register_req_t *req =
arch_get_register_req(co->aenv, irn, -1);
if (is_2addr_code(req)) { if (is_2addr_code(req)) {
ir_node *other = get_irn_n(skip_Proj(irn), req->other_same); const int *i;
if (! arch_irn_is(co->aenv, other, ignore)) for (i = req->other_same; i != ENDOF(req->other_same); ++i) {
add_edges(co, irn, other, co->get_costs(co, irn, other, 0)); ir_node *other;
if (*i == -1) break;
other = get_irn_n(skip_Proj(irn), *i);
if (! arch_irn_is(co->aenv, other, ignore))
add_edges(co, irn, other, co->get_costs(co, irn, other, 0));
}
} }
} }
} }
......
...@@ -546,7 +546,8 @@ ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *b ...@@ -546,7 +546,8 @@ ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *b
req = get_req(res, OUT_POS(0)); req = get_req(res, OUT_POS(0));
req->cls = cls; req->cls = cls;
req->type = arch_register_req_type_should_be_same; req->type = arch_register_req_type_should_be_same;
req->other_same = 0; req->other_same[0] = 0;
req->other_same[1] = -1;
return res; return res;
} }
......
...@@ -427,13 +427,18 @@ static void dump_affinities_walker(ir_node *irn, void *env) { ...@@ -427,13 +427,18 @@ static void dump_affinities_walker(ir_node *irn, void *env) {
/* should_be_equal constraints are affinites */ /* should_be_equal constraints are affinites */
for (pos = 0, max = get_irn_arity(irn); pos<max; ++pos) { for (pos = 0, max = get_irn_arity(irn); pos<max; ++pos) {
req = arch_get_register_req(raenv->aenv, irn, pos); req = arch_get_register_req(raenv->aenv, irn, pos);
if (arch_register_req_is(req, should_be_same)) { if (arch_register_req_is(req, should_be_same)) {
ir_node *other = get_irn_n(skip_Proj(irn), req->other_same); const int* i;
if(arch_irn_is(raenv->aenv, other, ignore)) { for (i = req->other_same; i != ENDOF(req->other_same); ++i) {
vi2 = be_get_var_info(other); ir_node *other;
if (*i == -1) break;
fprintf(raenv->f, "(%d, %d, %d)\n", vi1->var_nr, vi2->var_nr, get_affinity_weight(irn)); other = get_irn_n(skip_Proj(irn), *i);
if(arch_irn_is(raenv->aenv, other, ignore)) {
vi2 = be_get_var_info(other);
fprintf(raenv->f, "(%d, %d, %d)\n", vi1->var_nr, vi2->var_nr, get_affinity_weight(irn));
}
} }
} }
} }
......
...@@ -401,7 +401,7 @@ static void assure_should_be_same_requirements(ia32_code_gen_t *cg, ...@@ -401,7 +401,7 @@ static void assure_should_be_same_requirements(ia32_code_gen_t *cg,
if (!arch_register_req_is(req, should_be_same)) if (!arch_register_req_is(req, should_be_same))
continue; continue;
same_pos = req->other_same; same_pos = req->other_same[0];
/* get in and out register */ /* get in and out register */
out_reg = get_ia32_out_reg(node, i); out_reg = get_ia32_out_reg(node, i);
...@@ -543,7 +543,7 @@ static void fix_am_source(ir_node *irn, void *env) { ...@@ -543,7 +543,7 @@ static void fix_am_source(ir_node *irn, void *env) {
if (arch_register_req_is(reqs[i], should_be_same)) { if (arch_register_req_is(reqs[i], should_be_same)) {
/* get in and out register */ /* get in and out register */
const arch_register_t *out_reg = get_ia32_out_reg(irn, i); const arch_register_t *out_reg = get_ia32_out_reg(irn, i);
int same_pos = reqs[i]->other_same; int same_pos = reqs[i]->other_same[0];
ir_node *same_node = get_irn_n(irn, same_pos); ir_node *same_node = get_irn_n(irn, same_pos);
const arch_register_t *same_reg const arch_register_t *same_reg
= arch_get_irn_register(arch_env, same_node); = arch_get_irn_register(arch_env, same_node);
......
...@@ -96,7 +96,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, ...@@ -96,7 +96,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
} }
if (reqs[i]->type & arch_register_req_type_should_be_same) { if (reqs[i]->type & arch_register_req_type_should_be_same) {
ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same)); ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same[0]));
if (reqs[i]->other_same[1] != -1)
ir_fprintf(F, " or %+F", get_irn_n(n, reqs[i]->other_same[1]));
} }
if (reqs[i]->type & arch_register_req_type_should_be_different) { if (reqs[i]->type & arch_register_req_type_should_be_different) {
......
...@@ -364,7 +364,7 @@ ProduceVal => { ...@@ -364,7 +364,7 @@ ProduceVal => {
Add => { Add => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4", "none", "flags" ] }, reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5", "none", "flags" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. add%M %binop', emit => '. add%M %binop',
am => "full,binary", am => "full,binary",
...@@ -394,7 +394,7 @@ AddMem8Bit => { ...@@ -394,7 +394,7 @@ AddMem8Bit => {
}, },
Adc => { Adc => {
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right", "eflags" ], ins => [ "base", "index", "mem", "left", "right", "eflags" ],
emit => '. adc%M %binop', emit => '. adc%M %binop',
am => "full,binary", am => "full,binary",
...@@ -438,7 +438,7 @@ l_Mul => { ...@@ -438,7 +438,7 @@ l_Mul => {
IMul => { IMul => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. imul%M %binop', emit => '. imul%M %binop',
am => "source,binary", am => "source,binary",
...@@ -471,7 +471,7 @@ l_IMul => { ...@@ -471,7 +471,7 @@ l_IMul => {
And => { And => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
am => "full,binary", am => "full,binary",
emit => '. and%M %binop', emit => '. and%M %binop',
...@@ -502,7 +502,7 @@ AndMem8Bit => { ...@@ -502,7 +502,7 @@ AndMem8Bit => {
Or => { Or => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
am => "full,binary", am => "full,binary",
emit => '. or%M %binop', emit => '. or%M %binop',
...@@ -533,7 +533,7 @@ OrMem8Bit => { ...@@ -533,7 +533,7 @@ OrMem8Bit => {
Xor => { Xor => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
am => "full,binary", am => "full,binary",
emit => '. xor%M %binop', emit => '. xor%M %binop',
...@@ -1339,7 +1339,7 @@ xZero => { ...@@ -1339,7 +1339,7 @@ xZero => {
xAdd => { xAdd => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. add%XXM %binop', emit => '. add%XXM %binop',
latency => 4, latency => 4,
...@@ -1349,7 +1349,7 @@ xAdd => { ...@@ -1349,7 +1349,7 @@ xAdd => {
xMul => { xMul => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. mul%XXM %binop', emit => '. mul%XXM %binop',
latency => 4, latency => 4,
...@@ -1359,7 +1359,7 @@ xMul => { ...@@ -1359,7 +1359,7 @@ xMul => {
xMax => { xMax => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. max%XXM %binop', emit => '. max%XXM %binop',
latency => 2, latency => 2,
...@@ -1369,7 +1369,7 @@ xMax => { ...@@ -1369,7 +1369,7 @@ xMax => {
xMin => { xMin => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. min%XXM %binop', emit => '. min%XXM %binop',
latency => 2, latency => 2,
...@@ -1379,7 +1379,7 @@ xMin => { ...@@ -1379,7 +1379,7 @@ xMin => {
xAnd => { xAnd => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. andp%XSD %binop', emit => '. andp%XSD %binop',
latency => 3, latency => 3,
...@@ -1389,7 +1389,7 @@ xAnd => { ...@@ -1389,7 +1389,7 @@ xAnd => {
xOr => { xOr => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. orp%XSD %binop', emit => '. orp%XSD %binop',
units => [ "SSE" ], units => [ "SSE" ],
...@@ -1398,7 +1398,7 @@ xOr => { ...@@ -1398,7 +1398,7 @@ xOr => {
xXor => { xXor => {
irn_flags => "R", irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] }, reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ], ins => [ "base", "index", "mem", "left", "right" ],
emit => '. xorp%XSD %binop', emit => '. xorp%XSD %binop',
latency => 3, latency => 3,
......
...@@ -3087,7 +3087,8 @@ void parse_asm_constraint(int pos, constraint_t *constraint, const char *c) ...@@ -3087,7 +3087,8 @@ void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
req->cls = other_constr->cls; req->cls = other_constr->cls;
req->type = arch_register_req_type_should_be_same; req->type = arch_register_req_type_should_be_same;
req->limited = NULL; req->limited = NULL;
req->other_same = pos; req->other_same[0] = pos;
req->other_same[1] = -1;
req->other_different = -1; req->other_different = -1;
/* switch constraints. This is because in firm we have same_as /* switch constraints. This is because in firm we have same_as
......
...@@ -94,7 +94,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, ...@@ -94,7 +94,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
} }
if (reqs[i]->type & arch_register_req_type_should_be_same) { if (reqs[i]->type & arch_register_req_type_should_be_same) {
ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same)); ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same[0]));
if (reqs[i]->other_same[1] != -1)
ir_fprintf(F, " or %+F", get_irn_n(n, reqs[i]->other_same[1]));
} }
if (reqs[i]->type & arch_register_req_type_should_be_different) { if (reqs[i]->type & arch_register_req_type_should_be_different) {
......
...@@ -91,7 +91,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, ...@@ -91,7 +91,9 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
} }
if (reqs[i]->type & arch_register_req_type_should_be_same) { if (reqs[i]->type & arch_register_req_type_should_be_same) {
ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same)); ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same[0]));
if (reqs[i]->other_same[1] != -1)
ir_fprintf(F, " or %+F", get_irn_n(n, reqs[i]->other_same[1]));
} }
if (reqs[i]->type & arch_register_req_type_should_be_different) { if (reqs[i]->type & arch_register_req_type_should_be_different) {
......
...@@ -963,6 +963,7 @@ sub build_subset_class_func { ...@@ -963,6 +963,7 @@ sub build_subset_class_func {
my $has_limit = 0; my $has_limit = 0;
my $limit_name; my $limit_name;
my $same_pos = undef; my $same_pos = undef;
my $same_pos2 = undef;
my $different_pos = undef; my $different_pos = undef;
my $temp; my $temp;
my @obst_init; my @obst_init;
...@@ -985,22 +986,26 @@ sub build_subset_class_func { ...@@ -985,22 +986,26 @@ sub build_subset_class_func {
# set/unset registers # set/unset registers
CHECK_REQS: foreach (@regs) { CHECK_REQS: foreach (@regs) {
if (/(!)?$outin\_r(\d+)/) { if (/(!)?$outin\_r(\d+)/) {
if (($1 && defined($different_pos)) || (!$1 && defined($same_pos))) { if (($1 && defined($different_pos)) || (!$1 && defined($same_pos2))) {
print STDERR "Multiple in/out references of same type in one requirement not allowed.\n"; print STDERR "Multiple in/out references of same type in one requirement not allowed.\n";
return (undef, undef, undef, undef); return (undef, undef, undef, undef, undef);
} }
if ($1) { if ($1) {
$different_pos = $is_in ? -$2 : $2 - 1; $different_pos = $is_in ? -$2 : $2 - 1;
} else { } else {
$same_pos = $is_in ? -$2 : $2 - 1; if (!defined($same_pos)) {
$same_pos = $is_in ? -$2 : $2 - 1;
} else {
$same_pos2 = $is_in ? -$2 : $2 - 1;
}
} }
$class = $idx_class[$2 - 1]; $class = $idx_class[$2 - 1];
next CHECK_REQS; next CHECK_REQS;
} elsif (/!in/) { } elsif (/!in/) {
$class = $idx_class[0]; $class = $idx_class[0];
return ($class, "NULL", undef, 666); return ($class, "NULL", undef, undef, 666);
} }
# check for negate # check for negate
...@@ -1009,7 +1014,7 @@ CHECK_REQS: foreach (@regs) { ...@@ -1009,7 +1014,7 @@ CHECK_REQS: foreach (@regs) {
# we have seen a positiv constraint as first one but this one is negative # we have seen a positiv constraint as first one but this one is negative
# this doesn't make sense # this doesn't make sense
print STDERR "Mixed positive and negative constraints for the same slot are not allowed.\n"; print STDERR "Mixed positive and negative constraints for the same slot are not allowed.\n";
return (undef, undef, undef, undef); return (undef, undef, undef, undef, undef);
} }
if (!defined($neg)) { if (!defined($neg)) {
...@@ -1023,7 +1028,7 @@ CHECK_REQS: foreach (@regs) { ...@@ -1023,7 +1028,7 @@ CHECK_REQS: foreach (@regs) {
# we have seen a negative constraint as first one but this one is positive # we have seen a negative constraint as first one but this one is positive
# this doesn't make sense # this doesn't make sense
print STDERR "Mixed positive and negative constraints for the same slot are not allowed.\n"; print STDERR "Mixed positive and negative constraints for the same slot are not allowed.\n";
return (undef, undef, undef, undef); return (undef, undef, undef, undef, undef);
} }
$has_limit = 1; $has_limit = 1;
...@@ -1034,7 +1039,7 @@ CHECK_REQS: foreach (@regs) { ...@@ -1034,7 +1039,7 @@ CHECK_REQS: foreach (@regs) {
$temp = get_reg_class($_); $temp = get_reg_class($_);
if (!defined($temp)) { if (!defined($temp)) {
print STDERR "Unknown register '$_'!\n"; print STDERR "Unknown register '$_'!\n";
return (undef, undef, undef, undef); return (undef, undef, undef, undef, undef);
} }
# set class # set class
...@@ -1043,7 +1048,7 @@ CHECK_REQS: foreach (@regs) { ...@@ -1043,7 +1048,7 @@ CHECK_REQS: foreach (@regs) {
} elsif ($class ne $temp) { } elsif ($class ne $temp) {
# all registers must belong to the same class # all registers must belong to the same class
print STDERR "Registerclass mismatch. '$_' is not member of class '$class'.\n"; print STDERR "Registerclass mismatch. '$_' is not member of class '$class'.\n";
return (undef, undef, undef, undef); return (undef, undef, undef, undef, undef);
} }
# calculate position inside the initializer bitfield (only 32 bits per # calculate position inside the initializer bitfield (only 32 bits per
...@@ -1073,7 +1078,7 @@ CHECK_REQS: foreach (@regs) { ...@@ -1073,7 +1078,7 @@ CHECK_REQS: foreach (@regs) {
if(defined($limit_bitsets{$limit_name})) { if(defined($limit_bitsets{$limit_name})) {
$limit_name = $limit_bitsets{$limit_name}; $limit_name = $limit_bitsets{$limit_name};
return ($class, $limit_name, $same_pos, $different_pos); return ($class, $limit_name, $same_pos, $same_pos2, $different_pos);
} }
$limit_bitsets{$limit_name} = $limit_name; $limit_bitsets{$limit_name} = $limit_name;
...@@ -1111,7 +1116,7 @@ CHECK_REQS: foreach (@regs) { ...@@ -1111,7 +1116,7 @@ CHECK_REQS: foreach (@regs) {
push(@obst_limit_func, " };\n"); push(@obst_limit_func, " };\n");
} }