Commit 3047ff94 authored by Matthias Braun's avatar Matthias Braun
Browse files

addressmode for compares works now

[r14832]
parent f17f2942
......@@ -804,6 +804,15 @@ static int ia32_possible_memory_operand(const void *self, const ir_node *irn, un
return 1;
}
static void exchange_left_right(ir_node *node)
{
ir_node *tmp = get_irn_n(node, 3);
set_irn_n(node, 3, get_irn_n(node, 2));
set_irn_n(node, 2, tmp);
set_ia32_pncode(node, get_inversed_pnc(get_ia32_pncode(node)));
}
static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node *spill, unsigned int i) {
const ia32_irn_ops_t *ops = self;
ia32_code_gen_t *cg = ops->cg;
......@@ -811,9 +820,7 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node
assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
if (i == 2) {
ir_node *tmp = get_irn_n(irn, 3);
set_irn_n(irn, 3, get_irn_n(irn, 2));
set_irn_n(irn, 2, tmp);
exchange_left_right(irn);
}
set_ia32_op_type(irn, ia32_AddrModeS);
......@@ -826,7 +833,10 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node
set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
set_irn_n(irn, 4, spill);
//FIXME DBG_OPT_AM_S(reload, irn);
/* immediates are only allowed on the right side */
if(i == 2 && is_ia32_Immediate(get_irn_n(irn, 2))) {
exchange_left_right(irn);
}
}
static const be_abi_callbacks_t ia32_abi_callbacks = {
......
......@@ -401,11 +401,10 @@ void emit_ia32_Immediate(ia32_emit_env_t *env, const ir_node *node);
*/
void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
int right_pos;
const ir_node *right_op;
const ir_node *right_op = get_irn_n(node, 3);
switch(get_ia32_op_type(node)) {
case ia32_Normal:
right_op = get_irn_n(node, 3);
if(is_ia32_Immediate(right_op)) {
emit_ia32_Immediate(env, right_op);
be_emit_cstring(env, ", ");
......@@ -438,19 +437,31 @@ void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
}
break;
case ia32_AddrModeS:
ia32_emit_am(env, node);
be_emit_cstring(env, ", ");
if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
assert(!produces_result(node) && "Source AM with Const must not produce result");
assert(!produces_result(node) &&
"Source AM with Const must not produce result");
ia32_emit_immediate(env, node);
be_emit_cstring(env, ", ");
ia32_emit_am(env, node);
} else if(is_ia32_Immediate(right_op)) {
assert(!produces_result(node) &&
"Source AM with Const must not produce result");
emit_ia32_Immediate(env, right_op);
be_emit_cstring(env, ", ");
ia32_emit_am(env, node);
} else if (produces_result(node)) {
ia32_emit_am(env, node);
be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
} else {
ia32_emit_am(env, node);
be_emit_cstring(env, ", ");
ia32_emit_source_register(env, node, 2);
}
break;
case ia32_AddrModeD:
right_pos = get_irn_arity(node) == 5 ? 3 : 2;
right_pos = get_irn_arity(node) >= 5 ? 3 : 2;
right_op = get_irn_n(node, right_pos);
if(is_ia32_Immediate(right_op)) {
emit_ia32_Immediate(env, right_op);
......@@ -821,7 +832,9 @@ void finish_CondJmp(ia32_emit_env_t *env, const ir_node *node, ir_mode *mode,
*/
static
void CondJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
be_emit_cstring(env, "\tcmp ");
be_emit_cstring(env, "\tcmp");
ia32_emit_mode_suffix(env, node);
be_emit_char(env, ' ');
ia32_emit_binop(env, node);
be_emit_finish_line_gas(env, node);
......@@ -841,7 +854,10 @@ void emit_ia32_CondJmp(ia32_emit_env_t *env, const ir_node *node) {
*/
static
void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
be_emit_cstring(env, "\ttest ");
be_emit_cstring(env, "\ttest");
ia32_emit_mode_suffix(env, node);
be_emit_char(env, ' ');
ia32_emit_binop(env, node);
be_emit_finish_line_gas(env, node);
......
......@@ -1135,7 +1135,9 @@ static void merge_loadstore_lea(ir_node *irn, ir_node *lea) {
* Sets new_right index of irn to right and new_left index to left.
* Also exchange left and right
*/
static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right, int new_left, int new_right) {
static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right,
int new_left, int new_right)
{
ir_node *temp;
set_irn_n(irn, new_right, *right);
......@@ -1178,7 +1180,7 @@ static void optimize_lea(ia32_code_gen_t *cg, ir_node *irn) {
DB((dbg, LEVEL_1, "transformed into %+F\n", res));
else
DB((dbg, LEVEL_1, "not transformed\n"));
} else if (is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn)) {
} else if (is_ia32_Ld(irn) || is_ia32_St(irn)) {
/* - Load -> LEA into Load } TODO: If the LEA is used by more than one Load/Store */
/* - Store -> LEA into Store } it might be better to keep the LEA */
ir_node *left = get_irn_n(irn, 0);
......@@ -1191,7 +1193,7 @@ static void optimize_lea(ia32_code_gen_t *cg, ir_node *irn) {
foreach_out_edge_safe(left, edge, ne) {
src = get_edge_src_irn(edge);
if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src) || is_ia32_Store8Bit(src))) {
if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src))) {
DBG((dbg, LEVEL_1, "\nmerging %+F into %+F\n", left, irn));
if (! is_ia32_got_lea(src))
merge_loadstore_lea(src, left);
......@@ -1345,7 +1347,7 @@ static void optimize_am(ir_node *irn, void *env) {
&dest_out_reg_req_0
};
if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn))
if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn))
return;
if (is_ia32_Lea(irn))
return;
......@@ -1623,6 +1625,11 @@ static void optimize_am(ir_node *irn, void *env) {
}
need_exchange_on_fail = 0;
/* immediates are only allowed on the right side */
if(is_ia32_Immediate(left)) {
exchange_left_right(irn, &left, &right, 3, 2);
}
DB((dbg, LEVEL_1, "merged with %+F into source AM\n", load));
}
......
......@@ -1745,6 +1745,7 @@ static ir_node *try_create_TestJmp(ir_node *block, ir_node *node, long pnc)
res = new_rd_ia32_TestJmp(dbgi, current_ir_graph, block, noreg, noreg,
new_cmp_a, new_cmp_b, nomem, pnc);
set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
return res;
......@@ -1853,11 +1854,7 @@ static ir_node *gen_Cond(ir_node *node) {
set_ia32_commutative(res);
}
// Matze: disabled for now, because the default collect_spills_walker
// is not able to detect the mode of the spilled value
// moreover, the lea optimize phase freely exchanges left/right
// without updating the pnc
//set_ia32_am_support(res, ia32_am_Source | ia32_am_binary);
set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment