+ } /* if (store) */
+ else if (get_ia32_am_support(irn) & ia32_am_Source) {
+ /* There was no store, check if we still can optimize for source address mode */
+ check_am_src = 1;
+ }
+ } /* if (support AM Dest) */
+ else if (get_ia32_am_support(irn) & ia32_am_Source) {
+ /* op doesn't support am AM Dest -> check for AM Source */
+ check_am_src = 1;
+ }
+
+ /* was exchanged but optimize failed: exchange back */
+ if (need_exchange_on_fail) {
+ exchange_left_right(irn, &left, &right, 3, 2);
+ cand = orig_cand;
+ }
+
+ need_exchange_on_fail = 0;
+
+ /* normalize commutative ops */
+ if (check_am_src && node_is_ia32_comm(irn) && (cand == IA32_AM_CAND_LEFT)) {
+
+ /* Assure that right operand is always a Load if there is one */
+ /* because non-commutative ops can only use Source AM if the */
+ /* right operand is a Load, so we only need to check the right */
+ /* operand afterwards. */
+
+ exchange_left_right(irn, &left, &right, 3, 2);
+ need_exchange_on_fail = 1;
+
+ /* now: load is left */
+ cand = IA32_AM_CAND_RIGHT;
+ }
+
+ /* optimize op -> Load iff Load is only used by this op */
+ /* and right operand is a Load which only used by this irn */
+ if (check_am_src &&
+ (cand & IA32_AM_CAND_RIGHT) &&
+ (ia32_get_irn_n_edges(right) == 1))
+ {
+ ir_node *load = get_Proj_pred(right);
+
+ addr_b = get_irn_n(load, 0);
+ addr_i = get_irn_n(load, 1);
+
+ /* set new base, index and attributes */
+ set_irn_n(irn, 0, addr_b);
+ set_irn_n(irn, 1, addr_i);
+ add_ia32_am_offs(irn, get_ia32_am_offs(load));
+ set_ia32_am_scale(irn, get_ia32_am_scale(load));
+ set_ia32_am_flavour(irn, get_ia32_am_flavour(load));
+ set_ia32_op_type(irn, ia32_AddrModeS);
+ set_ia32_frame_ent(irn, get_ia32_frame_ent(load));
+ set_ia32_ls_mode(irn, get_ia32_ls_mode(load));
+
+ set_ia32_am_sc(irn, get_ia32_am_sc(load));
+ if (is_ia32_am_sc_sign(load))
+ set_ia32_am_sc_sign(irn);
+
+ /* clear remat flag */
+ set_ia32_flags(irn, get_ia32_flags(irn) & ~arch_irn_flags_rematerializable);
+
+ if (is_ia32_use_frame(load))
+ set_ia32_use_frame(irn);
+
+ /* connect to Load memory and disconnect Load */
+ if (get_irn_arity(irn) == 5) {
+ /* binary AMop */
+ set_irn_n(irn, 4, get_irn_n(load, 2));
+ set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
+ } else {
+ assert(get_irn_arity(irn) == 4);
+ /* unary AMop */
+ set_irn_n(irn, 3, get_irn_n(load, 2));
+ set_irn_n(irn, 2, ia32_get_admissible_noreg(cg, irn, 2));