-static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, ir_node *noreg) {
- ir_graph *irg = get_irn_irg(irn);
- dbg_info *dbg = get_irn_dbg_info(irn);
- ir_node *block = get_nodes_block(irn);
- ir_node *res = irn;
- ir_node *shift = NULL;
- ir_node *lea_o = NULL;
- ir_node *lea = NULL;
- char *offs = NULL;
- const char *offs_cnst = NULL;
- char *offs_lea = NULL;
- int scale = 0;
- int isadd = 0;
- int dolea = 0;
- int have_am_sc = 0;
- int am_sc_sign = 0;
- ident *am_sc = NULL;
- entity *lea_ent = NULL;
- ir_node *left, *right, *temp;
- ir_node *base, *index;
- ia32_am_flavour_t am_flav;
- DEBUG_ONLY(firm_dbg_module_t *mod = cg->mod;)
-
- if (is_ia32_Add(irn))
- isadd = 1;
-
- left = get_irn_n(irn, 2);
- right = get_irn_n(irn, 3);
-
- /* "normalize" arguments in case of add with two operands */
- if (isadd && ! be_is_NoReg(cg, right)) {
- /* put LEA == ia32_am_O as right operand */
- if (is_ia32_Lea(left) && get_ia32_am_flavour(left) == ia32_am_O) {
- set_irn_n(irn, 2, right);
- set_irn_n(irn, 3, left);
- temp = left;
- left = right;
- right = temp;
- }
-
- /* put LEA != ia32_am_O as left operand */
- if (is_ia32_Lea(right) && get_ia32_am_flavour(right) != ia32_am_O) {
- set_irn_n(irn, 2, right);
- set_irn_n(irn, 3, left);
- temp = left;
- left = right;
- right = temp;
- }
-
- /* put SHL as left operand iff left is NOT a LEA */
- if (! is_ia32_Lea(left) && pred_is_specific_node(right, is_ia32_Shl)) {
- set_irn_n(irn, 2, right);
- set_irn_n(irn, 3, left);
- temp = left;
- left = right;
- right = temp;
- }
- }
-
- base = left;
- index = noreg;
- offs = NULL;
- scale = 0;
- am_flav = 0;
-
- /* check for operation with immediate */
- if (is_ia32_ImmConst(irn)) {
- DBG((mod, LEVEL_1, "\tfound op with imm const"));
-
- offs_cnst = get_ia32_cnst(irn);
- dolea = 1;
- }
- else if (is_ia32_ImmSymConst(irn)) {
- DBG((mod, LEVEL_1, "\tfound op with imm symconst"));
-
- have_am_sc = 1;
- dolea = 1;
- am_sc = get_ia32_id_cnst(irn);
- am_sc_sign = is_ia32_am_sc_sign(irn);
- }
-
- /* determine the operand which needs to be checked */
- temp = be_is_NoReg(cg, right) ? left : right;
-
- /* check if right operand is AMConst (LEA with ia32_am_O) */
- /* but we can only eat it up if there is no other symconst */
- /* because the linker won't accept two symconsts */
- if (! have_am_sc && is_ia32_Lea(temp) && get_ia32_am_flavour(temp) == ia32_am_O) {
- DBG((mod, LEVEL_1, "\tgot op with LEA am_O"));
-
- offs_lea = get_ia32_am_offs(temp);
- am_sc = get_ia32_am_sc(temp);
- am_sc_sign = is_ia32_am_sc_sign(temp);
- have_am_sc = 1;
- dolea = 1;
- lea_o = temp;
-
- if (temp == base)
- base = noreg;
- else if (temp == right)
- right = noreg;
- }
+static void peephole_ia32_Const(ir_node *node)
+{
+ const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
+ const arch_register_t *reg;
+ ir_graph *irg = current_ir_graph;
+ ir_node *block;
+ dbg_info *dbgi;
+ ir_node *produceval;
+ ir_node *xor;
+ ir_node *noreg;
+
+ /* try to transform a mov 0, reg to xor reg reg */
+ if (attr->offset != 0 || attr->symconst != NULL)
+ return;
+ if (ia32_cg_config.use_mov_0)
+ return;
+ /* xor destroys the flags, so no-one must be using them */
+ if (be_peephole_get_value(CLASS_ia32_flags, REG_EFLAGS) != NULL)
+ return;