-/**
- * Compares the base and index addr and the load/store entities
- * and returns 1 if they are equal.
- */
-static int load_store_addr_is_equal(const ir_node *load, const ir_node *store,
- const ir_node *addr_b, const ir_node *addr_i)
-{
- int is_equal = (addr_b == get_irn_n(load, 0)) && (addr_i == get_irn_n(load, 1));
- entity *lent = get_ia32_frame_ent(load);
- entity *sent = get_ia32_frame_ent(store);
- ident *lid = get_ia32_am_sc(load);
- ident *sid = get_ia32_am_sc(store);
- char *loffs = get_ia32_am_offs(load);
- char *soffs = get_ia32_am_offs(store);
-
- /* are both entities set and equal? */
- if (is_equal && (lent || sent))
- is_equal = lent && sent && (lent == sent);
-
- /* are address mode idents set and equal? */
- if (is_equal && (lid || sid))
- is_equal = lid && sid && (lid == sid);
-
- /* are offsets set and equal */
- if (is_equal && (loffs || soffs))
- is_equal = loffs && soffs && strcmp(loffs, soffs) == 0;
-
- /* are the load and the store of the same mode? */
- is_equal = is_equal ? get_ia32_ls_mode(load) == get_ia32_ls_mode(store) : 0;
-
- return is_equal;
-}
-
-typedef enum _ia32_take_lea_attr {
- IA32_LEA_ATTR_NONE = 0,
- IA32_LEA_ATTR_BASE = (1 << 0),
- IA32_LEA_ATTR_INDEX = (1 << 1),
- IA32_LEA_ATTR_OFFS = (1 << 2),
- IA32_LEA_ATTR_SCALE = (1 << 3),
- IA32_LEA_ATTR_AMSC = (1 << 4),
- IA32_LEA_ATTR_FENT = (1 << 5)
-} ia32_take_lea_attr;
-
-/**
- * Decides if we have to keep the LEA operand or if we can assimilate it.
- */
-static int do_new_lea(ir_node *irn, ir_node *base, ir_node *index, ir_node *lea,
- int have_am_sc, ia32_code_gen_t *cg)
-{
- ir_node *lea_base = get_irn_n(lea, 0);
- ir_node *lea_idx = get_irn_n(lea, 1);
- entity *irn_ent = get_ia32_frame_ent(irn);
- entity *lea_ent = get_ia32_frame_ent(lea);
- int ret_val = 0;
- int is_noreg_base = be_is_NoReg(cg, base);
- int is_noreg_index = be_is_NoReg(cg, index);
- ia32_am_flavour_t am_flav = get_ia32_am_flavour(lea);
-
- /* If the Add and the LEA both have a different frame entity set: keep */
- if (irn_ent && lea_ent && (irn_ent != lea_ent))
- return IA32_LEA_ATTR_NONE;
- else if (! irn_ent && lea_ent)
- ret_val |= IA32_LEA_ATTR_FENT;
-
- /* If the Add and the LEA both have already an address mode symconst: keep */
- if (have_am_sc && get_ia32_am_sc(lea))
- return IA32_LEA_ATTR_NONE;
- else if (get_ia32_am_sc(lea))
- ret_val |= IA32_LEA_ATTR_AMSC;
-
- /* Check the different base-index combinations */
-
- if (! is_noreg_base && ! is_noreg_index) {
- /* Assimilate if base is the lea and the LEA is just a Base + Offset calculation */
- if ((base == lea) && ! (am_flav & ia32_I ? 1 : 0)) {
- if (am_flav & ia32_O)
- ret_val |= IA32_LEA_ATTR_OFFS;
-
- ret_val |= IA32_LEA_ATTR_BASE;
- }
- else
- return IA32_LEA_ATTR_NONE;
- }
- else if (! is_noreg_base && is_noreg_index) {
- /* Base is set but index not */
- if (base == lea) {
- /* Base points to LEA: assimilate everything */
- if (am_flav & ia32_O)
- ret_val |= IA32_LEA_ATTR_OFFS;
- if (am_flav & ia32_S)
- ret_val |= IA32_LEA_ATTR_SCALE;
- if (am_flav & ia32_I)
- ret_val |= IA32_LEA_ATTR_INDEX;
-
- ret_val |= IA32_LEA_ATTR_BASE;
- }
- else if (am_flav & ia32_B ? 0 : 1) {
- /* Base is not the LEA but the LEA is an index only calculation: assimilate */
- if (am_flav & ia32_O)
- ret_val |= IA32_LEA_ATTR_OFFS;
- if (am_flav & ia32_S)
- ret_val |= IA32_LEA_ATTR_SCALE;
-
- ret_val |= IA32_LEA_ATTR_INDEX;