- /* optimize op -> Load iff Load is only used by this op */
- /* and left operand is a Load which only used by this irn */
- if (check_am_src &&
- pred_is_specific_nodeblock(block, left, is_ia32_Ld) &&
- (ia32_get_irn_n_edges(left) == 1))
- {
- left = get_Proj_pred(left);
-
- addr_b = get_irn_n(left, 0);
- addr_i = get_irn_n(left, 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(left));
- set_ia32_am_scale(irn, get_ia32_am_scale(left));
- set_ia32_am_flavour(irn, get_ia32_am_flavour(left));
- set_ia32_op_type(irn, ia32_AddrModeS);
- set_ia32_frame_ent(irn, get_ia32_frame_ent(left));
- set_ia32_ls_mode(irn, get_ia32_ls_mode(left));
-
- set_ia32_am_sc(irn, get_ia32_am_sc(left));
- if (is_ia32_am_sc_sign(left))
- 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(left))
- set_ia32_use_frame(irn);
-
- /* connect to Load memory */
- if (get_irn_arity(irn) == 5) {
- /* binary AMop */
- set_irn_n(irn, 4, get_irn_n(left, 2));
- }
- else {
- /* unary AMop */
- set_irn_n(irn, 3, get_irn_n(left, 2));
- }
+ need_exchange_on_fail = 0;
+
+ /* normalize commutative ops */
+ if (check_am_src && node_is_ia32_comm(irn) && (cand == IA32_AM_CAND_RIGHT)) {
+
+ /* Assure that left operand is always a Load if there is one */
+ /* because non-commutative ops can only use Source AM if the */
+ /* left operand is a Load, so we only need to check the left */
+ /* operand afterwards. */
+
+ exchange_left_right(irn, &left, &right, 3, 2);
+ need_exchange_on_fail = 1;
+
+ /* now: load is left */
+ cand = IA32_AM_CAND_LEFT;
+ }
+
+ /* optimize op -> Load iff Load is only used by this op */
+ /* and left operand is a Load which only used by this irn */
+ if (check_am_src &&
+ (cand & IA32_AM_CAND_LEFT) &&
+ (ia32_get_irn_n_edges(left) == 1))
+ {
+ left = get_Proj_pred(left);
+
+ addr_b = get_irn_n(left, 0);
+ addr_i = get_irn_n(left, 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(left));
+ set_ia32_am_scale(irn, get_ia32_am_scale(left));
+ set_ia32_am_flavour(irn, get_ia32_am_flavour(left));
+ set_ia32_op_type(irn, ia32_AddrModeS);
+ set_ia32_frame_ent(irn, get_ia32_frame_ent(left));
+ set_ia32_ls_mode(irn, get_ia32_ls_mode(left));
+
+ set_ia32_am_sc(irn, get_ia32_am_sc(left));
+ if (is_ia32_am_sc_sign(left))
+ 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(left))
+ set_ia32_use_frame(irn);
+
+ /* connect to Load memory */
+ if (get_irn_arity(irn) == 5) {
+ /* binary AMop */
+ set_irn_n(irn, 4, get_irn_n(left, 2));
+
+ /* this is only needed for Compares, but currently ALL nodes
+ * have this attribute :-) */
+ set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn)));