rtx addr_for_mem_ref (struct mem_address *addr, addr_space_t as, bool really_expand) { enum machine_mode address_mode = targetm.addr_space.address_mode (as); enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); rtx address, sym, bse, idx, st, off; struct mem_addr_template *templ; if (addr->step && !integer_onep (addr->step)) st = immed_double_int_const (tree_to_double_int (addr->step), pointer_mode); else st = NULL_RTX; if (addr->offset && !integer_zerop (addr->offset)) off = immed_double_int_const (double_int_sext (tree_to_double_int (addr->offset), TYPE_PRECISION (TREE_TYPE (addr->offset))), pointer_mode); else off = NULL_RTX; if (!really_expand) { unsigned int templ_index = TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off); if (templ_index >= VEC_length (mem_addr_template, mem_addr_template_list)) VEC_safe_grow_cleared (mem_addr_template, gc, mem_addr_template_list, templ_index + 1); /* Reuse the templates for addresses, so that we do not waste memory. */ templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index); if (!templ->ref) { sym = (addr->symbol ? gen_rtx_SYMBOL_REF (pointer_mode, ggc_strdup ("test_symbol")) : NULL_RTX); bse = (addr->base ? gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 1) : NULL_RTX); idx = (addr->index ? gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 2) : NULL_RTX); gen_addr_rtx (pointer_mode, sym, bse, idx, st? const0_rtx : NULL_RTX, off? const0_rtx : NULL_RTX, &templ->ref, &templ->step_p, &templ->off_p); } if (st) *templ->step_p = st; if (off) *templ->off_p = off; return templ->ref; } /* Otherwise really expand the expressions. */ sym = (addr->symbol ? expand_expr (addr->symbol, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); bse = (addr->base ? expand_expr (addr->base, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); idx = (addr->index ? expand_expr (addr->index, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); gen_addr_rtx (pointer_mode, sym, bse, idx, st, off, &address, NULL, NULL); if (pointer_mode != address_mode) address = convert_memory_address (address_mode, address); return address; }
double_int double_int_ext_for_comb (double_int cst, aff_tree *comb) { return double_int_sext (cst, TYPE_PRECISION (comb->type)); }