From 3047ff9491225ce680b2792ac2eb612c12ade0a8 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 28 Jun 2007 22:27:32 +0000 Subject: [PATCH] addressmode for compares works now [r14832] --- ir/be/ia32/bearch_ia32.c | 18 ++++++++++++++---- ir/be/ia32/ia32_emitter.c | 32 ++++++++++++++++++++++++-------- ir/be/ia32/ia32_optimize.c | 15 +++++++++++---- ir/be/ia32/ia32_transform.c | 7 ++----- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 774f25574..bcfa97381 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -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 = { diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index ca08ba6de..0ed60ca9b 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -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); diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 50cd0c8b9..ffbe8dfa6 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -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)); } diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 644bffa8e..e15582d55 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -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)); -- 2.20.1