aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorBen Elliston <bje@au.ibm.com>2009-10-26 21:57:10 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2009-10-26 21:57:10 +0000
commitd4ebfa65c962f1f0b50223e34184dc5a81d907c6 (patch)
tree0b006fa60cd37b4bd974ed32a7adc7f005e9eb0b /gcc/expr.c
parent09e881c9e21a9209b2092e400ea4c38948614f78 (diff)
downloadgcc-d4ebfa65c962f1f0b50223e34184dc5a81d907c6.zip
gcc-d4ebfa65c962f1f0b50223e34184dc5a81d907c6.tar.gz
gcc-d4ebfa65c962f1f0b50223e34184dc5a81d907c6.tar.bz2
tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.
2009-10-26 Ben Elliston <bje@au.ibm.com> Michael Meissner <meissner@linux.vnet.ibm.com> Ulrich Weigand <uweigand@de.ibm.com> * doc/tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document. (TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise. (TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise. * target.h (struct target_def): Add pointer_mode, address_mode, and valid_pointer_mode to addr_space substructure. * target-def.h (TARGET_ADDR_SPACE_POINTER_MODE): Define. (TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise. (TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise. (TARGET_ADDR_SPACE_HOOKS): Add them. * targhooks.c (target_default_pointer_address_modes_p): New function. * target.h (target_default_pointer_address_modes_p): Add prototype. * targhooks.c (default_addr_space_pointer_mode): New function. (default_addr_space_address_mode): Likewise. (default_addr_space_valid_pointer_mode): Likewise. * targhooks.h (default_addr_space_pointer_mode): Add prototype. (default_addr_space_address_mode): Likewise. (default_addr_space_valid_pointer_mode): Likewise. * output.h (default_valid_pointer_mode): Move to ... * targhooks.h (default_valid_pointer_mode): ... here. * varasm.c (default_valid_pointer_mode): Move to ... * targhooks.c (default_valid_pointer_mode): ... here. * varasm.c (output_constant): Use targetm.addr_space.valid_pointer_mode instead of targetm.valid_pointer_mode. * fold-const.c (fit_double_type): Use int_or_pointer_precision. * tree.c (integer_pow2p): Likewise. (tree_log2): Likewise. (tree_floor_log2): Likewise. (signed_or_unsigned_type_for): Support pointer type of different size. (int_or_pointer_precision): New function. * tree.h (int_or_pointer_precision): Add prototype. * stor-layout.c (layout_type): Set TYPE_PRECISION for offset types. * varasm.c (initializer_constant_valid_p): Use TYPE_PRECISION of incoming pointer type instead of POINTER_SIZE. * tree.c (build_pointer_type): Use appropriate pointer mode instead of ptr_mode. (build_reference_type): Likewise. * expr.c (store_expr): Likewise. (expand_expr_addr_expr): Likewise. * tree-vect-data-refs.c (vect_create_data_ref_ptr): Likewise. * cfgexpand.c (expand_debug_expr): Likewise. * auto-inc-dec.c: Include "target.h". (try_merge): Use appropriate address mode instead of Pmode. (find_inc): Likewise. * combine.c (find_split_point): Likewise. * cselib.c (cselib_record_sets): Likewise. * dse.c (replace_inc_dec): Likewise. (canon_address): Likewise. * var-tracking.c (replace_expr_with_values): Likewise. (count_uses): Likewise. (add_uses): Likewise. (add_stores): Likewise. * emit-rtl.c: Include "target.h". (adjust_address_1): Use appropriate address mode instead of Pmode. (offset_address): Likewise. * explow.c (break_out_memory_refs): Likewise. (memory_address_addr_space): Likewise. (promote_mode): Likewise. * expr.c (move_by_pieces): Likewise. (emit_block_move_via_loop): Likewise. (store_by_pieces): Likewise. (store_by_pieces_1): Likewise. (expand_assignment): Likewise. (store_constructor): Likewise. (expand_expr_addr_expr): Likewise. (expand_expr_real_1): Likewise. * cfgexpand.c (expand_debug_expr): Likewise. * ifcvt.c (noce_try_cmove_arith): Likewise. * regcprop.c (kill_autoinc_value): Likewise. * regmove.c (try_auto_increment): Likewise. * reload.c (find_reloads): Likewise. (find_reloads_address): Likewise. (find_reloads_address_1): Likewise. * sched-deps.c: Include "target.h". (sched_analyze_1): Use appropriate address mode instead of Pmode. (sched_analyze_2): Likewise. * sel-sched-dump.c: Include "target.h". (debug_mem_addr_value): Use appropriate address mode instead of Pmode. * stor-layout.c (layout_type): Likewise. * tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Likewise. (multiplier_allowed_in_address_p): Likewise. (get_address_cost): Likewise. * varasm.c (make_decl_rtl): Likewise. * expr.c (expand_assignment): Always convert offsets to appropriate address mode. (store_expr): Likewise. (store_constructor): Likewise. (expand_expr_real_1): Likewise. * reload.h (form_sum): Add MODE argument. * reload.c (form_sum): Add MODE argument, use it instead of Pmode. Update recursive calls. (subst_indexed_address): Update calls to form_sum. * tree-flow.h (addr_for_mem_ref): Add ADDRSPACE argument. * tree-ssa-address.c: Include "target.h". (templates): Replace by ... (mem_addr_template_list): ... this new vector. (TEMPL_IDX): Handle address space numbers. (gen_addr_rtx): Add address mode argument, use it instead of Pmode. (addr_for_mem_ref): Add ADDRSPACE argument. Use per-address-space instead of global cache. Update call to gen_addr_rtx. (valid_mem_ref_p): Update call to addr_for_mem_ref. * expr.c (expand_expr_real_1): Update call to addr_for_mem_ref. * rtl.h (convert_memory_address_addr_space): Add prototype. (convert_memory_address): Define as macro. * explow.c (convert_memory_address): Rename to ... (convert_memory_address_addr_space): ... this. Add ADDRSPACE argument. Use appropriate pointer and address modes instead of ptr_mode / Pmode. Update recursive calls. (memory_address_addr_space): Call convert_memory_address_addr_space. * expmed.c (make_tree): Likewise. * expr.c (expand_assignment): Likewise. (expand_expr_addr_expr_1): Likewise. Also, add ADDRSPACE argument. (expand_expr_addr_expr): Likewise. Also, update call. * alias.c (find_base_value): Guard pointer size optimizations. (find_base_term): Likewise. * rtlanal.c (nonzero_bits1): Likewise. (num_sign_bit_copies1): Likewise. * simplify-rtx.c (simplify_unary_operation_1): Likewise. * Makefile.in (tree-ssa-address.o): Add $(TARGET_H) dependency. (emit-rtl.o): Likewise. (auto-inc-dec.o): Likewise. (sched-deps.o): Likewise. Co-Authored-By: Michael Meissner <meissner@linux.vnet.ibm.com> Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com> From-SVN: r153573
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c144
1 files changed, 90 insertions, 54 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 5e8fae1..e62b530 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -877,6 +877,8 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
unsigned int align, int endp)
{
struct move_by_pieces_d data;
+ enum machine_mode to_addr_mode, from_addr_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (from));
rtx to_addr, from_addr = XEXP (from, 0);
unsigned int max_size = MOVE_MAX_PIECES + 1;
enum machine_mode mode = VOIDmode, tmode;
@@ -888,6 +890,7 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
data.from_addr = from_addr;
if (to)
{
+ to_addr_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to));
to_addr = XEXP (to, 0);
data.to = to;
data.autinc_to
@@ -898,6 +901,7 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
}
else
{
+ to_addr_mode = VOIDmode;
to_addr = NULL_RTX;
data.to = NULL_RTX;
data.autinc_to = 1;
@@ -933,32 +937,34 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
{
- data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
+ data.from_addr = copy_to_mode_reg (from_addr_mode,
+ plus_constant (from_addr, len));
data.autinc_from = 1;
data.explicit_inc_from = -1;
}
if (USE_LOAD_POST_INCREMENT (mode) && ! data.autinc_from)
{
- data.from_addr = copy_addr_to_reg (from_addr);
+ data.from_addr = copy_to_mode_reg (from_addr_mode, from_addr);
data.autinc_from = 1;
data.explicit_inc_from = 1;
}
if (!data.autinc_from && CONSTANT_P (from_addr))
- data.from_addr = copy_addr_to_reg (from_addr);
+ data.from_addr = copy_to_mode_reg (from_addr_mode, from_addr);
if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
{
- data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
+ data.to_addr = copy_to_mode_reg (to_addr_mode,
+ plus_constant (to_addr, len));
data.autinc_to = 1;
data.explicit_inc_to = -1;
}
if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
{
- data.to_addr = copy_addr_to_reg (to_addr);
+ data.to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
data.autinc_to = 1;
data.explicit_inc_to = 1;
}
if (!data.autinc_to && CONSTANT_P (to_addr))
- data.to_addr = copy_addr_to_reg (to_addr);
+ data.to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
}
tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
@@ -1013,7 +1019,8 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
else
- data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
+ data.to_addr = copy_to_mode_reg (to_addr_mode,
+ plus_constant (data.to_addr,
-1));
}
to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
@@ -1468,6 +1475,10 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
unsigned int align ATTRIBUTE_UNUSED)
{
rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
+ enum machine_mode x_addr_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+ enum machine_mode y_addr_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (y));
enum machine_mode iter_mode;
iter_mode = GET_MODE (size);
@@ -1487,9 +1498,13 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
emit_jump (cmp_label);
emit_label (top_label);
- tmp = convert_modes (Pmode, iter_mode, iter, true);
- x_addr = gen_rtx_PLUS (Pmode, x_addr, tmp);
- y_addr = gen_rtx_PLUS (Pmode, y_addr, tmp);
+ tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
+ x_addr = gen_rtx_PLUS (x_addr_mode, x_addr, tmp);
+
+ if (x_addr_mode != y_addr_mode)
+ tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
+ y_addr = gen_rtx_PLUS (y_addr_mode, y_addr, tmp);
+
x = change_address (x, QImode, x_addr);
y = change_address (y, QImode, y_addr);
@@ -2384,6 +2399,8 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
void *constfundata, unsigned int align, bool memsetp, int endp)
{
+ enum machine_mode to_addr_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to));
struct store_by_pieces_d data;
if (len == 0)
@@ -2412,7 +2429,8 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
else
- data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
+ data.to_addr = copy_to_mode_reg (to_addr_mode,
+ plus_constant (data.to_addr,
-1));
}
to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
@@ -2467,6 +2485,8 @@ static void
store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
unsigned int align ATTRIBUTE_UNUSED)
{
+ enum machine_mode to_addr_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (data->to));
rtx to_addr = XEXP (data->to, 0);
unsigned int max_size = STORE_MAX_PIECES + 1;
enum machine_mode mode = VOIDmode, tmode;
@@ -2498,7 +2518,8 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
{
- data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
+ data->to_addr = copy_to_mode_reg (to_addr_mode,
+ plus_constant (to_addr, data->len));
data->autinc_to = 1;
data->explicit_inc_to = -1;
}
@@ -2506,13 +2527,13 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
if (USE_STORE_POST_INCREMENT (mode) && ! data->reverse
&& ! data->autinc_to)
{
- data->to_addr = copy_addr_to_reg (to_addr);
+ data->to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
data->autinc_to = 1;
data->explicit_inc_to = 1;
}
if ( !data->autinc_to && CONSTANT_P (to_addr))
- data->to_addr = copy_addr_to_reg (to_addr);
+ data->to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
}
tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
@@ -4214,6 +4235,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
if (offset != 0)
{
+ enum machine_mode address_mode;
rtx offset_rtx;
if (!MEM_P (to_rtx))
@@ -4226,13 +4248,10 @@ expand_assignment (tree to, tree from, bool nontemporal)
}
offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (offset_rtx) != Pmode)
- offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-#else
- if (GET_MODE (offset_rtx) != ptr_mode)
- offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-#endif
+ address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to_rtx));
+ if (GET_MODE (offset_rtx) != address_mode)
+ offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
/* A constant address in TO_RTX can have VOIDmode, we must not try
to call force_reg for that case. Avoid that case. */
@@ -4371,7 +4390,10 @@ expand_assignment (tree to, tree from, bool nontemporal)
else
{
if (POINTER_TYPE_P (TREE_TYPE (to)))
- value = convert_memory_address (GET_MODE (to_rtx), value);
+ value = convert_memory_address_addr_space
+ (GET_MODE (to_rtx), value,
+ TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
+
emit_move_insn (to_rtx, value);
}
preserve_temp_slots (to_rtx);
@@ -4731,6 +4753,11 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
else
{
+ enum machine_mode pointer_mode
+ = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (target));
+
/* Compute the size of the data to copy from the string. */
tree copy_size
= size_binop_loc (loc, MIN_EXPR,
@@ -4743,14 +4770,14 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
rtx label = 0;
/* Copy that much. */
- copy_size_rtx = convert_to_mode (ptr_mode, copy_size_rtx,
+ copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
TYPE_UNSIGNED (sizetype));
emit_block_move (target, temp, copy_size_rtx,
(call_param_p
? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
/* Figure out how much is left in TARGET that we have to clear.
- Do all calculations in ptr_mode. */
+ Do all calculations in pointer_mode. */
if (CONST_INT_P (copy_size_rtx))
{
size = plus_constant (size, -INTVAL (copy_size_rtx));
@@ -4763,11 +4790,10 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
copy_size_rtx, NULL_RTX, 0,
OPTAB_LIB_WIDEN);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (copy_size_rtx) != Pmode)
- copy_size_rtx = convert_to_mode (Pmode, copy_size_rtx,
+ if (GET_MODE (copy_size_rtx) != address_mode)
+ copy_size_rtx = convert_to_mode (address_mode,
+ copy_size_rtx,
TYPE_UNSIGNED (sizetype));
-#endif
target = offset_address (target, copy_size_rtx,
highest_pow2_factor (copy_size));
@@ -5257,6 +5283,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
if (offset)
{
+ enum machine_mode address_mode;
rtx offset_rtx;
offset
@@ -5267,13 +5294,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
offset_rtx = expand_normal (offset);
gcc_assert (MEM_P (to_rtx));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (offset_rtx) != Pmode)
- offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-#else
- if (GET_MODE (offset_rtx) != ptr_mode)
- offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-#endif
+ address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to_rtx));
+ if (GET_MODE (offset_rtx) != address_mode)
+ offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
to_rtx = offset_address (to_rtx, offset_rtx,
highest_pow2_factor (offset));
@@ -6796,7 +6820,7 @@ expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
static rtx
expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
- enum expand_modifier modifier)
+ enum expand_modifier modifier, addr_space_t as)
{
rtx result, subtarget;
tree inner, offset;
@@ -6823,7 +6847,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
case CONST_DECL:
/* Recurse and make the output_constant_def clause above handle this. */
return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target,
- tmode, modifier);
+ tmode, modifier, as);
case REALPART_EXPR:
/* The real part of the complex number is always first, therefore
@@ -6913,7 +6937,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
TYPE_ALIGN (TREE_TYPE (inner)) = TYPE_ALIGN (TREE_TYPE (exp));
TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
}
- result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier);
+ result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
if (offset)
{
@@ -6925,8 +6949,8 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
modifier == EXPAND_INITIALIZER
? EXPAND_INITIALIZER : EXPAND_NORMAL);
- result = convert_memory_address (tmode, result);
- tmp = convert_memory_address (tmode, tmp);
+ result = convert_memory_address_addr_space (tmode, result, as);
+ tmp = convert_memory_address_addr_space (tmode, tmp, as);
if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
result = gen_rtx_PLUS (tmode, result, tmp);
@@ -6959,6 +6983,9 @@ static rtx
expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier)
{
+ addr_space_t as = ADDR_SPACE_GENERIC;
+ enum machine_mode address_mode = Pmode;
+ enum machine_mode pointer_mode = ptr_mode;
enum machine_mode rmode;
rtx result;
@@ -6966,14 +6993,21 @@ expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
if (tmode == VOIDmode)
tmode = TYPE_MODE (TREE_TYPE (exp));
+ if (POINTER_TYPE_P (TREE_TYPE (exp)))
+ {
+ as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
+ address_mode = targetm.addr_space.address_mode (as);
+ pointer_mode = targetm.addr_space.pointer_mode (as);
+ }
+
/* We can get called with some Weird Things if the user does silliness
like "(short) &a". In that case, convert_memory_address won't do
the right thing, so ignore the given target mode. */
- if (tmode != Pmode && tmode != ptr_mode)
- tmode = Pmode;
+ if (tmode != address_mode && tmode != pointer_mode)
+ tmode = address_mode;
result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
- tmode, modifier);
+ tmode, modifier, as);
/* Despite expand_expr claims concerning ignoring TMODE when not
strictly convenient, stuff breaks if we don't honor it. Note
@@ -6982,7 +7016,7 @@ expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
if (rmode == VOIDmode)
rmode = tmode;
if (rmode != tmode)
- result = convert_memory_address (tmode, result);
+ result = convert_memory_address_addr_space (tmode, result, as);
return result;
}
@@ -8657,6 +8691,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
tree exp1 = treeop0;
addr_space_t as = ADDR_SPACE_GENERIC;
+ enum machine_mode address_mode = Pmode;
if (modifier != EXPAND_WRITE)
{
@@ -8668,7 +8703,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
}
if (POINTER_TYPE_P (TREE_TYPE (exp1)))
- as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1)));
+ {
+ as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1)));
+ address_mode = targetm.addr_space.address_mode (as);
+ }
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address_addr_space (mode, op0, as);
@@ -8676,7 +8714,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (code == ALIGN_INDIRECT_REF)
{
int align = TYPE_ALIGN_UNIT (type);
- op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
+ op0 = gen_rtx_AND (address_mode, op0, GEN_INT (-align));
op0 = memory_address_addr_space (mode, op0, as);
}
@@ -8719,7 +8757,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
struct mem_address addr;
get_address_description (exp, &addr);
- op0 = addr_for_mem_ref (&addr, true);
+ op0 = addr_for_mem_ref (&addr, as, true);
op0 = memory_address_addr_space (mode, op0, as);
temp = gen_rtx_MEM (mode, op0);
set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
@@ -9011,18 +9049,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (offset)
{
+ enum machine_mode address_mode;
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
EXPAND_SUM);
gcc_assert (MEM_P (op0));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (offset_rtx) != Pmode)
- offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-#else
- if (GET_MODE (offset_rtx) != ptr_mode)
- offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-#endif
+ address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (op0));
+ if (GET_MODE (offset_rtx) != address_mode)
+ offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
if (GET_MODE (op0) == BLKmode
/* A constant address in OP0 can have VOIDmode, we must