- conv_mode = get_ia32_ls_mode(node);
- pred_mode = get_ia32_ls_mode(pred);
- if(get_mode_size_bits(conv_mode) < get_mode_size_bits(pred_mode))
- return;
-
- /* we can't eliminate an upconv signed->unsigned */
- if (get_mode_size_bits(conv_mode) != get_mode_size_bits(pred_mode) &&
- !get_mode_sign(conv_mode) && get_mode_sign(pred_mode))
- return;
-
- /* kill the conv */
- exchange(node, pred);
-}
-
-static void optimize_node(ir_node *node, void *env)
-{
- ia32_code_gen_t *cg = env;
-
- optimize_load_conv(node);
- optimize_conv_store(node);
- optimize_conv_conv(node);
- optimize_lea(cg, node);
-}
-
-/**
- * Checks for address mode patterns and performs the
- * necessary transformations.
- * This function is called by a walker.
- */
-static void optimize_am(ir_node *irn, void *env) {
- ia32_am_opt_env_t *am_opt_env = env;
- ia32_code_gen_t *cg = am_opt_env->cg;
- ir_graph *irg = get_irn_irg(irn);
- heights_t *h = am_opt_env->h;
- ir_node *block, *left, *right;
- ir_node *store, *load, *mem_proj;
- ir_node *addr_b, *addr_i;
- int need_exchange_on_fail = 0;
- ia32_am_type_t am_support;
- ia32_am_arity_t am_arity;
- ia32_am_cand_t cand;
- ia32_am_cand_t orig_cand;
- int dest_possible;
- int source_possible;
-
- static const arch_register_req_t dest_out_reg_req_0 = {
- arch_register_req_type_none,
- NULL, /* regclass */
- NULL, /* limit bitset */
- -1, /* same pos */
- -1 /* different pos */
- };
- static const arch_register_req_t *dest_am_out_reqs[] = {
- &dest_out_reg_req_0
- };
-
- if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn))
- return;
- if (is_ia32_Lea(irn))
- return;
-
- am_support = get_ia32_am_support(irn);
- am_arity = get_ia32_am_arity(irn);
- block = get_nodes_block(irn);
-
- /* fold following patterns:
- * - op -> Load into AMop with am_Source
- * conditions:
- * - op is am_Source capable AND
- * - the Load is only used by this op AND
- * - the Load is in the same block
- * - Store -> op -> Load into AMop with am_Dest
- * conditions:
- * - op is am_Dest capable AND
- * - the Store uses the same address as the Load AND
- * - the Load is only used by this op AND
- * - the Load and Store are in the same block AND
- * - nobody else uses the result of the op
- */
- if (am_support == ia32_am_None)
- return;
-
- assert(am_arity == ia32_am_unary || am_arity == ia32_am_binary);
-
- cand = is_am_candidate(h, block, irn);
- if (cand == IA32_AM_CAND_NONE)
- return;
-
- orig_cand = cand;
- DBG((dbg, LEVEL_1, "\tfound address mode candidate %+F (candleft %d candright %d)... \n", irn,
- cand & IA32_AM_CAND_LEFT, cand & IA32_AM_CAND_RIGHT));
-
- left = get_irn_n(irn, 2);
- if (am_arity == ia32_am_unary) {
- assert(get_irn_arity(irn) >= 4);
- right = left;
- assert(cand == IA32_AM_CAND_BOTH);
- } else {
- assert(get_irn_arity(irn) >= 5);
- right = get_irn_n(irn, 3);
- }
-
- dest_possible = am_support & ia32_am_Dest ? 1 : 0;
- source_possible = am_support & ia32_am_Source ? 1 : 0;
-
- DBG((dbg, LEVEL_2, "\tdest_possible %d source_possible %d ... \n", dest_possible, source_possible));
-
- if (dest_possible) {
- addr_b = NULL;
- addr_i = NULL;
- store = NULL;
-
- /* we should only have 1 user which is a store */
- if (ia32_get_irn_n_edges(irn) == 1) {
- ir_node *succ = get_edge_src_irn(get_irn_out_edge_first(irn));
-
- if (is_ia32_xStore(succ) || is_ia32_Store(succ)) {
- store = succ;
- addr_b = get_irn_n(store, 0);
- addr_i = get_irn_n(store, 1);
+ conv_mode = get_ia32_ls_mode(node);
+ conv_mode_bits = get_mode_size_bits(conv_mode);
+ pred_mode = get_ia32_ls_mode(pred);
+ pred_mode_bits = get_mode_size_bits(pred_mode);
+
+ if(conv_mode_bits == pred_mode_bits
+ && get_mode_sign(conv_mode) == get_mode_sign(pred_mode)) {
+ result_conv = pred_proj;
+ } else if(conv_mode_bits <= pred_mode_bits) {
+ /* if 2nd conv is smaller then first conv, then we can always take the
+ * 2nd conv */
+ if(get_irn_n_edges(pred_proj) == 1) {
+ result_conv = pred_proj;
+ set_ia32_ls_mode(pred, conv_mode);
+
+ /* Argh:We must change the opcode to 8bit AND copy the register constraints */
+ if (get_mode_size_bits(conv_mode) == 8) {
+ set_irn_op(pred, op_ia32_Conv_I2I8Bit);
+ set_ia32_in_req_all(pred, get_ia32_in_req_all(node));