summaryrefslogtreecommitdiff
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
parent09e881c9e21a9209b2092e400ea4c38948614f78 (diff)
downloadgcc-d4ebfa65c962f1f0b50223e34184dc5a81d907c6.tar.gz
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
-rw-r--r--gcc/ChangeLog137
-rw-r--r--gcc/Makefile.in8
-rw-r--r--gcc/alias.c22
-rw-r--r--gcc/auto-inc-dec.c34
-rw-r--r--gcc/cfgexpand.c17
-rw-r--r--gcc/combine.c7
-rw-r--r--gcc/cselib.c8
-rw-r--r--gcc/doc/tm.texi24
-rw-r--r--gcc/dse.c20
-rw-r--r--gcc/emit-rtl.c11
-rw-r--r--gcc/explow.c41
-rw-r--r--gcc/expmed.c7
-rw-r--r--gcc/expr.c144
-rw-r--r--gcc/fold-const.c8
-rw-r--r--gcc/ifcvt.c5
-rw-r--r--gcc/output.h1
-rw-r--r--gcc/regcprop.c2
-rw-r--r--gcc/regmove.c4
-rw-r--r--gcc/reload.c42
-rw-r--r--gcc/reload.h2
-rw-r--r--gcc/reload1.c2
-rw-r--r--gcc/rtl.h5
-rw-r--r--gcc/rtlanal.c26
-rw-r--r--gcc/sched-deps.c11
-rw-r--r--gcc/sel-sched-dump.c6
-rw-r--r--gcc/simplify-rtx.c12
-rw-r--r--gcc/stor-layout.c26
-rw-r--r--gcc/target-def.h16
-rw-r--r--gcc/target.h16
-rw-r--r--gcc/targhooks.c56
-rw-r--r--gcc/targhooks.h5
-rw-r--r--gcc/tree-flow.h2
-rw-r--r--gcc/tree-ssa-address.c106
-rw-r--r--gcc/tree-ssa-loop-ivopts.c59
-rw-r--r--gcc/tree-vect-data-refs.c7
-rw-r--r--gcc/tree.c70
-rw-r--r--gcc/tree.h1
-rw-r--r--gcc/var-tracking.c30
-rw-r--r--gcc/varasm.c32
39 files changed, 756 insertions, 276 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ebe6aec2ba4..658274da303 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,143 @@
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.
+
+2009-10-26 Ben Elliston <bje@au.ibm.com>
+ Michael Meissner <meissner@linux.vnet.ibm.com>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
* doc/extend.texi (Named Address Spaces): New section.
* coretypes.h (addr_space_t): New type.
(ADDR_SPACE_GENERIC): New define.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 934c4ed1b3a..5dd47e57f39 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2432,7 +2432,7 @@ tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \
output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(TREE_PASS_H) $(FLAGS_H) $(TREE_INLINE_H) $(RECOG_H) insn-config.h \
- $(EXPR_H) gt-tree-ssa-address.h $(GGC_H) tree-affine.h
+ $(EXPR_H) gt-tree-ssa-address.h $(GGC_H) tree-affine.h $(TARGET_H)
tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \
$(TREE_INLINE_H) output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -2824,7 +2824,7 @@ emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
$(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
$(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
- $(REAL_H) $(DF_H) $(PARAMS_H)
+ $(REAL_H) $(DF_H) $(PARAMS_H) $(TARGET_H)
real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -3034,7 +3034,7 @@ alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \
$(REGS_H) $(FLAGS_H) output.h $(FUNCTION_H) $(EXCEPT_H) $(TOPLEV_H) $(RECOG_H) \
- $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H)
+ $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H)
cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
$(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) $(FUNCTION_H) $(EXCEPT_H) $(GGC_H) \
$(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h \
@@ -3215,7 +3215,7 @@ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
- ira.h $(PARAMS_H) $(TM_P_H) ira.h
+ ira.h $(PARAMS_H) $(TM_P_H) ira.h $(TARGET_H)
sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
diff --git a/gcc/alias.c b/gcc/alias.c
index b6d0b7eccc5..40226f26b17 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1060,6 +1060,11 @@ find_base_value (rtx src)
return 0;
case TRUNCATE:
+ /* As we do not know which address space the pointer is refering to, we can
+ handle this only if the target does not support different pointer or
+ address modes depending on the address space. */
+ if (!target_default_pointer_address_modes_p ())
+ break;
if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
break;
/* Fall through. */
@@ -1074,6 +1079,12 @@ find_base_value (rtx src)
case ZERO_EXTEND:
case SIGN_EXTEND: /* used for NT/Alpha pointers */
+ /* As we do not know which address space the pointer is refering to, we can
+ handle this only if the target does not support different pointer or
+ address modes depending on the address space. */
+ if (!target_default_pointer_address_modes_p ())
+ break;
+
{
rtx temp = find_base_value (XEXP (src, 0));
@@ -1466,6 +1477,11 @@ find_base_term (rtx x)
return REG_BASE_VALUE (x);
case TRUNCATE:
+ /* As we do not know which address space the pointer is refering to, we can
+ handle this only if the target does not support different pointer or
+ address modes depending on the address space. */
+ if (!target_default_pointer_address_modes_p ())
+ return 0;
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
return 0;
/* Fall through. */
@@ -1480,6 +1496,12 @@ find_base_term (rtx x)
case ZERO_EXTEND:
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
+ /* As we do not know which address space the pointer is refering to, we can
+ handle this only if the target does not support different pointer or
+ address modes depending on the address space. */
+ if (!target_default_pointer_address_modes_p ())
+ return 0;
+
{
rtx temp = find_base_term (XEXP (x, 0));
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 929a2dcade8..3b3006c985f 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "df.h"
#include "dbgcnt.h"
+#include "target.h"
/* This pass was originally removed from flow.c. However there is
almost nothing that remains of that code.
@@ -613,6 +614,7 @@ try_merge (void)
/* The width of the mem being accessed. */
int size = GET_MODE_SIZE (GET_MODE (mem));
rtx last_insn = NULL;
+ enum machine_mode reg_mode = GET_MODE (inc_reg);
switch (inc_insn.form)
{
@@ -667,33 +669,33 @@ try_merge (void)
case SIMPLE_PRE_INC: /* ++size */
if (dump_file)
fprintf (dump_file, "trying SIMPLE_PRE_INC\n");
- return attempt_change (gen_rtx_PRE_INC (Pmode, inc_reg), inc_reg);
+ return attempt_change (gen_rtx_PRE_INC (reg_mode, inc_reg), inc_reg);
break;
case SIMPLE_POST_INC: /* size++ */
if (dump_file)
fprintf (dump_file, "trying SIMPLE_POST_INC\n");
- return attempt_change (gen_rtx_POST_INC (Pmode, inc_reg), inc_reg);
+ return attempt_change (gen_rtx_POST_INC (reg_mode, inc_reg), inc_reg);
break;
case SIMPLE_PRE_DEC: /* --size */
if (dump_file)
fprintf (dump_file, "trying SIMPLE_PRE_DEC\n");
- return attempt_change (gen_rtx_PRE_DEC (Pmode, inc_reg), inc_reg);
+ return attempt_change (gen_rtx_PRE_DEC (reg_mode, inc_reg), inc_reg);
break;
case SIMPLE_POST_DEC: /* size-- */
if (dump_file)
fprintf (dump_file, "trying SIMPLE_POST_DEC\n");
- return attempt_change (gen_rtx_POST_DEC (Pmode, inc_reg), inc_reg);
+ return attempt_change (gen_rtx_POST_DEC (reg_mode, inc_reg), inc_reg);
break;
case DISP_PRE: /* ++con */
if (dump_file)
fprintf (dump_file, "trying DISP_PRE\n");
- return attempt_change (gen_rtx_PRE_MODIFY (Pmode,
+ return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
inc_reg,
- gen_rtx_PLUS (Pmode,
+ gen_rtx_PLUS (reg_mode,
inc_reg,
inc_insn.reg1)),
inc_reg);
@@ -702,9 +704,9 @@ try_merge (void)
case DISP_POST: /* con++ */
if (dump_file)
fprintf (dump_file, "trying POST_DISP\n");
- return attempt_change (gen_rtx_POST_MODIFY (Pmode,
+ return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
inc_reg,
- gen_rtx_PLUS (Pmode,
+ gen_rtx_PLUS (reg_mode,
inc_reg,
inc_insn.reg1)),
inc_reg);
@@ -713,9 +715,9 @@ try_merge (void)
case REG_PRE: /* ++reg */
if (dump_file)
fprintf (dump_file, "trying PRE_REG\n");
- return attempt_change (gen_rtx_PRE_MODIFY (Pmode,
+ return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
inc_reg,
- gen_rtx_PLUS (Pmode,
+ gen_rtx_PLUS (reg_mode,
inc_reg,
inc_insn.reg1)),
inc_reg);
@@ -724,9 +726,9 @@ try_merge (void)
case REG_POST: /* reg++ */
if (dump_file)
fprintf (dump_file, "trying POST_REG\n");
- return attempt_change (gen_rtx_POST_MODIFY (Pmode,
+ return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
inc_reg,
- gen_rtx_PLUS (Pmode,
+ gen_rtx_PLUS (reg_mode,
inc_reg,
inc_insn.reg1)),
inc_reg);
@@ -1089,7 +1091,9 @@ find_inc (bool first_try)
we are going to increment the result of the add insn.
For this trick to be correct, the result reg of
the inc must be a valid addressing reg. */
- if (GET_MODE (inc_insn.reg_res) != Pmode)
+ addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
+ if (GET_MODE (inc_insn.reg_res)
+ != targetm.addr_space.address_mode (as))
{
if (dump_file)
fprintf (dump_file, "base reg mode failure.\n");
@@ -1138,7 +1142,9 @@ find_inc (bool first_try)
{
/* For this trick to be correct, the result reg of the inc
must be a valid addressing reg. */
- if (GET_MODE (inc_insn.reg_res) != Pmode)
+ addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
+ if (GET_MODE (inc_insn.reg_res)
+ != targetm.addr_space.address_mode (as))
{
if (dump_file)
fprintf (dump_file, "base reg mode failure.\n");
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 21b900a540a..fdc4de586ef 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2236,6 +2236,8 @@ expand_debug_expr (tree exp)
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
addr_space_t as;
+ enum machine_mode address_mode;
+ enum machine_mode pointer_mode;
switch (TREE_CODE_CLASS (TREE_CODE (exp)))
{
@@ -2434,15 +2436,18 @@ expand_debug_expr (tree exp)
else
as = ADDR_SPACE_GENERIC;
- gcc_assert (GET_MODE (op0) == Pmode
- || GET_MODE (op0) == ptr_mode
+ address_mode = targetm.addr_space.address_mode (as);
+ pointer_mode = targetm.addr_space.pointer_mode (as);
+
+ gcc_assert (GET_MODE (op0) == address_mode
+ || GET_MODE (op0) == pointer_mode
|| GET_CODE (op0) == CONST_INT
|| GET_CODE (op0) == CONST_DOUBLE);
if (TREE_CODE (exp) == ALIGN_INDIRECT_REF)
{
int align = TYPE_ALIGN_UNIT (TREE_TYPE (exp));
- op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
+ op0 = gen_rtx_AND (address_mode, op0, GEN_INT (-align));
}
op0 = gen_rtx_MEM (mode, op0);
@@ -2463,9 +2468,11 @@ expand_debug_expr (tree exp)
return NULL;
as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
+ address_mode = targetm.addr_space.address_mode (as);
+ pointer_mode = targetm.addr_space.pointer_mode (as);
- gcc_assert (GET_MODE (op0) == Pmode
- || GET_MODE (op0) == ptr_mode
+ gcc_assert (GET_MODE (op0) == address_mode
+ || GET_MODE (op0) == pointer_mode
|| GET_CODE (op0) == CONST_INT
|| GET_CODE (op0) == CONST_DOUBLE);
diff --git a/gcc/combine.c b/gcc/combine.c
index 89dc4154947..2311755691c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4159,9 +4159,12 @@ find_split_point (rtx *loc, rtx insn)
if (GET_CODE (XEXP (x, 0)) == CONST
|| GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+
SUBST (XEXP (x, 0),
- gen_rtx_LO_SUM (Pmode,
- gen_rtx_HIGH (Pmode, XEXP (x, 0)),
+ gen_rtx_LO_SUM (address_mode,
+ gen_rtx_HIGH (address_mode, XEXP (x, 0)),
XEXP (x, 0)));
return &XEXP (XEXP (x, 0), 0);
}
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 7065429be8b..0aa22a4fe1b 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1890,7 +1890,13 @@ cselib_record_sets (rtx insn)
src = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, src, dest);
sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1);
if (MEM_P (dest))
- sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), Pmode, 1);
+ {
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
+
+ sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0),
+ address_mode, 1);
+ }
else
sets[i].dest_addr_elt = 0;
}
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4a2fe56df95..26b5a14a3d7 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -9855,6 +9855,30 @@ Internally, address spaces are represented as a small integer in the
range 0 to 15 with address space 0 being reserved for the generic
address space.
+@deftypefn {Target Hook} {enum machine_mode} TARGET_ADDR_SPACE_POINTER_MODE (addr_space_t @var{address_space})
+Define this to return the machine mode to use for pointers to
+@var{address_space} if the target supports named address spaces.
+The default version of this hook returns @code{ptr_mode} for the
+generic address space only.
+@end deftypefn
+
+@deftypefn {Target Hook} {enum machine_mode} TARGET_ADDR_SPACE_ADDRESS_MODE (addr_space_t @var{address_space})
+Define this to return the machine mode to use for addresses in
+@var{address_space} if the target supports named address spaces.
+The default version of this hook returns @code{Pmode} for the
+generic address space only.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_ADDR_SPACE_VALID_POINTER_MODE (enum machine_mode @var{mode}, addr_space_t @var{as})
+Define this to return nonzero if the port can handle pointers
+with machine mode @var{mode} to address space @var{as}. This target
+hook is the same as the @code{TARGET_VALID_POINTER_MODE} target hook,
+except that it includes explicit named address space support. The default
+version of this hook returns true for the modes returned by either the
+@code{TARGET_ADDR_SPACE_POINTER_MODE} or @code{TARGET_ADDR_SPACE_ADDRESS_MODE}
+target hooks for the given address space.
+@end deftypefn
+
@deftypefn {Target Hook} {bool} TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P (enum machine_mode @var{mode}, rtx @var{exp}, bool @var{strict}, addr_space_t @var{as})
Define this to return true if @var{exp} is a valid address for mode
@var{mode} in the named address space @var{as}. The @var{strict}
diff --git a/gcc/dse.c b/gcc/dse.c
index f11c34a6c4c..a883bcd3d69 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -826,9 +826,9 @@ replace_inc_dec (rtx *r, void *d)
case POST_INC:
{
rtx r1 = XEXP (x, 0);
- rtx c = gen_int_mode (data->size, Pmode);
- emit_insn_before (gen_rtx_SET (Pmode, r1,
- gen_rtx_PLUS (Pmode, r1, c)),
+ rtx c = gen_int_mode (data->size, GET_MODE (r1));
+ emit_insn_before (gen_rtx_SET (VOIDmode, r1,
+ gen_rtx_PLUS (GET_MODE (r1), r1, c)),
data->insn);
return -1;
}
@@ -837,9 +837,9 @@ replace_inc_dec (rtx *r, void *d)
case POST_DEC:
{
rtx r1 = XEXP (x, 0);
- rtx c = gen_int_mode (-data->size, Pmode);
- emit_insn_before (gen_rtx_SET (Pmode, r1,
- gen_rtx_PLUS (Pmode, r1, c)),
+ rtx c = gen_int_mode (-data->size, GET_MODE (r1));
+ emit_insn_before (gen_rtx_SET (VOIDmode, r1,
+ gen_rtx_PLUS (GET_MODE (r1), r1, c)),
data->insn);
return -1;
}
@@ -851,7 +851,7 @@ replace_inc_dec (rtx *r, void *d)
insn that contained it. */
rtx add = XEXP (x, 0);
rtx r1 = XEXP (add, 0);
- emit_insn_before (gen_rtx_SET (Pmode, r1, add), data->insn);
+ emit_insn_before (gen_rtx_SET (VOIDmode, r1, add), data->insn);
return -1;
}
@@ -1068,6 +1068,8 @@ canon_address (rtx mem,
HOST_WIDE_INT *offset,
cselib_val **base)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
rtx mem_address = XEXP (mem, 0);
rtx expanded_address, address;
int expanded;
@@ -1107,7 +1109,7 @@ canon_address (rtx mem,
*alias_set_out = 0;
- cselib_lookup (mem_address, Pmode, 1);
+ cselib_lookup (mem_address, address_mode, 1);
if (dump_file)
{
@@ -1187,7 +1189,7 @@ canon_address (rtx mem,
}
}
- *base = cselib_lookup (address, Pmode, true);
+ *base = cselib_lookup (address, address_mode, true);
*group_id = -1;
if (*base == NULL)
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index baad4a85eef..d7600bccc26 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "df.h"
#include "params.h"
+#include "target.h"
/* Commonly used modes. */
@@ -1975,6 +1976,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
rtx size = 0;
unsigned int memalign = MEM_ALIGN (memref);
addr_space_t as = MEM_ADDR_SPACE (memref);
+ enum machine_mode address_mode = targetm.addr_space.address_mode (as);
int pbits;
/* If there are no changes, just return the original memory reference. */
@@ -1989,7 +1991,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
/* Convert a possibly large offset to a signed value within the
range of the target address space. */
- pbits = GET_MODE_BITSIZE (Pmode);
+ pbits = GET_MODE_BITSIZE (address_mode);
if (HOST_BITS_PER_WIDE_INT > pbits)
{
int shift = HOST_BITS_PER_WIDE_INT - pbits;
@@ -2005,7 +2007,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
&& offset >= 0
&& (unsigned HOST_WIDE_INT) offset
< GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
- addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0),
+ addr = gen_rtx_LO_SUM (address_mode, XEXP (addr, 0),
plus_constant (XEXP (addr, 1), offset));
else
addr = plus_constant (addr, offset);
@@ -2068,8 +2070,9 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{
rtx new_rtx, addr = XEXP (memref, 0);
addr_space_t as = MEM_ADDR_SPACE (memref);
+ enum machine_mode address_mode = targetm.addr_space.address_mode (as);
- new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
+ new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
/* At this point we don't know _why_ the address is invalid. It
could have secondary memory references, multiplies or anything.
@@ -2083,7 +2086,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
&& XEXP (addr, 0) == pic_offset_table_rtx)
{
addr = force_reg (GET_MODE (addr), addr);
- new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
+ new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
}
update_temp_slot_address (XEXP (memref, 0), new_rtx);
diff --git a/gcc/explow.c b/gcc/explow.c
index 1115f222c4c..c38682d4ce5 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -306,27 +306,27 @@ break_out_memory_refs (rtx x)
rtx op1 = break_out_memory_refs (XEXP (x, 1));
if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
- x = simplify_gen_binary (GET_CODE (x), Pmode, op0, op1);
+ x = simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, op1);
}
return x;
}
-/* Given X, a memory address in ptr_mode, convert it to an address
- in Pmode, or vice versa (TO_MODE says which way). We take advantage of
- the fact that pointers are not allowed to overflow by commuting arithmetic
- operations over conversions so that address arithmetic insns can be
- used. */
+/* Given X, a memory address in address space AS' pointer mode, convert it to
+ an address in the address space's address mode, or vice versa (TO_MODE says
+ which way). We take advantage of the fact that pointers are not allowed to
+ overflow by commuting arithmetic operations over conversions so that address
+ arithmetic insns can be used. */
rtx
-convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
- rtx x)
+convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
+ rtx x, addr_space_t as ATTRIBUTE_UNUSED)
{
#ifndef POINTERS_EXTEND_UNSIGNED
gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode);
return x;
#else /* defined(POINTERS_EXTEND_UNSIGNED) */
- enum machine_mode from_mode;
+ enum machine_mode pointer_mode, address_mode, from_mode;
rtx temp;
enum rtx_code code;
@@ -334,7 +334,9 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
if (GET_MODE (x) == to_mode)
return x;
- from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
+ pointer_mode = targetm.addr_space.pointer_mode (as);
+ address_mode = targetm.addr_space.address_mode (as);
+ from_mode = to_mode == pointer_mode ? address_mode : pointer_mode;
/* Here we handle some special cases. If none of them apply, fall through
to the default case. */
@@ -375,7 +377,8 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
case CONST:
return gen_rtx_CONST (to_mode,
- convert_memory_address (to_mode, XEXP (x, 0)));
+ convert_memory_address_addr_space
+ (to_mode, XEXP (x, 0), as));
break;
case PLUS:
@@ -389,10 +392,12 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
|| (GET_CODE (x) == PLUS
&& CONST_INT_P (XEXP (x, 1))
- && (XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1))
+ && (XEXP (x, 1) == convert_memory_address_addr_space
+ (to_mode, XEXP (x, 1), as)
|| POINTERS_EXTEND_UNSIGNED < 0)))
return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
- convert_memory_address (to_mode, XEXP (x, 0)),
+ convert_memory_address_addr_space
+ (to_mode, XEXP (x, 0), as),
XEXP (x, 1));
break;
@@ -413,13 +418,14 @@ rtx
memory_address_addr_space (enum machine_mode mode, rtx x, addr_space_t as)
{
rtx oldx = x;
+ enum machine_mode address_mode = targetm.addr_space.address_mode (as);
- x = convert_memory_address (Pmode, x);
+ x = convert_memory_address_addr_space (address_mode, x, as);
/* By passing constant addresses through registers
we get a chance to cse them. */
if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
- x = force_reg (Pmode, x);
+ x = force_reg (address_mode, x);
/* We get better cse by rejecting indirect addressing at this stage.
Let the combiner create indirect addresses where appropriate.
@@ -490,7 +496,7 @@ memory_address_addr_space (enum machine_mode mode, rtx x, addr_space_t as)
/* Last resort: copy the value to a register, since
the register is a valid address. */
else
- x = force_reg (Pmode, x);
+ x = force_reg (address_mode, x);
}
done:
@@ -801,7 +807,8 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, enum machine_mode mode,
case REFERENCE_TYPE:
case POINTER_TYPE:
*punsignedp = POINTERS_EXTEND_UNSIGNED;
- return Pmode;
+ return targetm.addr_space.address_mode
+ (TYPE_ADDR_SPACE (TREE_TYPE (type)));
break;
#endif
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 98a99a2b5f1..12370d07333 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -5089,10 +5089,11 @@ make_tree (tree type, rtx x)
default:
t = build_decl (RTL_LOCATION (x), VAR_DECL, NULL_TREE, type);
- /* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
- ptr_mode. So convert. */
+ /* If TYPE is a POINTER_TYPE, we might need to convert X from
+ address mode to pointer mode. */
if (POINTER_TYPE_P (type))
- x = convert_memory_address (TYPE_MODE (type), x);
+ x = convert_memory_address_addr_space
+ (TYPE_MODE (type), x, TYPE_ADDR_SPACE (TREE_TYPE (type)));
/* Note that we do *not* use SET_DECL_RTL here, because we do not
want set_decl_rtl to go adjusting REG_ATTRS for this temporary. */
diff --git a/gcc/expr.c b/gcc/expr.c
index 5e8fae123cb..e62b5302114 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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index aab4fac9edb..102929d1e20 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -206,15 +206,9 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
{
unsigned HOST_WIDE_INT low0 = l1;
HOST_WIDE_INT high0 = h1;
- unsigned int prec;
+ unsigned int prec = int_or_pointer_precision (type);
int sign_extended_type;
- if (POINTER_TYPE_P (type)
- || TREE_CODE (type) == OFFSET_TYPE)
- prec = POINTER_SIZE;
- else
- prec = TYPE_PRECISION (type);
-
/* Size types *are* sign extended. */
sign_extended_type = (!TYPE_UNSIGNED (type)
|| (TREE_CODE (type) == INTEGER_TYPE
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 8b1b4500e6f..d8d15a59be1 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1332,9 +1332,12 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
&& MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
&& if_info->branch_cost >= 5)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (a));
+
a = XEXP (a, 0);
b = XEXP (b, 0);
- x = gen_reg_rtx (Pmode);
+ x = gen_reg_rtx (address_mode);
is_mem = 1;
}
diff --git a/gcc/output.h b/gcc/output.h
index 9e2b704920a..5d771d7d06f 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -626,7 +626,6 @@ extern void default_emit_except_table_label (FILE *);
extern void default_internal_label (FILE *, const char *, unsigned long);
extern void default_file_start (void);
extern void file_end_indicate_exec_stack (void);
-extern bool default_valid_pointer_mode (enum machine_mode);
extern void default_elf_asm_output_external (FILE *file, tree,
const char *);
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index 893751886eb..ac8350d1f4e 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -247,7 +247,7 @@ kill_autoinc_value (rtx *px, void *data)
{
x = XEXP (x, 0);
kill_value (x, vd);
- set_value_regno (REGNO (x), Pmode, vd);
+ set_value_regno (REGNO (x), GET_MODE (x), vd);
return -1;
}
diff --git a/gcc/regmove.c b/gcc/regmove.c
index 4d45d5d1beb..581af4c7edc 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -185,7 +185,9 @@ try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
&SET_SRC (inc_insn_set),
XEXP (SET_SRC (inc_insn_set), 0), 1);
validate_change (insn, &XEXP (use, 0),
- gen_rtx_fmt_e (inc_code, Pmode, reg), 1);
+ gen_rtx_fmt_e (inc_code,
+ GET_MODE (XEXP (use, 0)), reg),
+ 1);
if (apply_change_group ())
{
/* If there is a REG_DEAD note on this insn, we must
diff --git a/gcc/reload.c b/gcc/reload.c
index 166bcb98611..3333697f2e0 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -3987,12 +3987,15 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& MEM_P (recog_data.operand[i]))
{
/* If the address to be reloaded is a VOIDmode constant,
- use Pmode as mode of the reload register, as would have
- been done by find_reloads_address. */
+ use the default address mode as mode of the reload register,
+ as would have been done by find_reloads_address. */
enum machine_mode address_mode;
address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
if (address_mode == VOIDmode)
- address_mode = Pmode;
+ {
+ addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
+ address_mode = targetm.addr_space.address_mode (as);
+ }
operand_reloadnum[i]
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
@@ -5113,7 +5116,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
That will at least work. */
find_reloads_address_part (ad, loc,
base_reg_class (mode, MEM, SCRATCH),
- Pmode, opnum, type, ind_levels);
+ GET_MODE (ad), opnum, type, ind_levels);
}
return ! removed_and;
}
@@ -5235,6 +5238,10 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
into a register. */
if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
{
+ enum machine_mode address_mode = GET_MODE (ad);
+ if (ad == VOIDmode)
+ address_mode = targetm.addr_space.address_mode (as);
+
/* If AD is an address in the constant pool, the MEM rtx may be shared.
Unshare it so we can safely alter it. */
if (memrefloc && GET_CODE (ad) == SYMBOL_REF
@@ -5247,7 +5254,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
}
find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH),
- Pmode, opnum, type, ind_levels);
+ address_mode, opnum, type, ind_levels);
return ! removed_and;
}
@@ -5334,16 +5341,12 @@ subst_reg_equivs (rtx ad, rtx insn)
This routine assumes both inputs are already in canonical form. */
rtx
-form_sum (rtx x, rtx y)
+form_sum (enum machine_mode mode, rtx x, rtx y)
{
rtx tem;
- enum machine_mode mode = GET_MODE (x);
-
- if (mode == VOIDmode)
- mode = GET_MODE (y);
- if (mode == VOIDmode)
- mode = Pmode;
+ gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
+ gcc_assert (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode);
if (CONST_INT_P (x))
return plus_constant (y, INTVAL (x));
@@ -5353,12 +5356,12 @@ form_sum (rtx x, rtx y)
tem = x, x = y, y = tem;
if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
- return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
+ return form_sum (mode, XEXP (x, 0), form_sum (mode, XEXP (x, 1), y));
/* Note that if the operands of Y are specified in the opposite
order in the recursive calls below, infinite recursion will occur. */
if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
- return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
+ return form_sum (mode, form_sum (mode, x, XEXP (y, 0)), XEXP (y, 1));
/* If both constant, encapsulate sum. Otherwise, just form sum. A
constant will have been placed second. */
@@ -5425,9 +5428,9 @@ subst_indexed_address (rtx addr)
/* Compute the sum. */
if (op2 != 0)
- op1 = form_sum (op1, op2);
+ op1 = form_sum (GET_MODE (addr), op1, op2);
if (op1 != 0)
- op0 = form_sum (op0, op1);
+ op0 = form_sum (GET_MODE (addr), op0, op1);
return op0;
}
@@ -5827,7 +5830,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
: reg_equiv_mem[regno]);
- int icode = (int) optab_handler (add_optab, Pmode)->insn_code;
+ int icode
+ = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
@@ -5835,9 +5839,9 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
#endif
&& ! (icode != CODE_FOR_nothing
&& ((*insn_data[icode].operand[0].predicate)
- (equiv, Pmode))
+ (equiv, GET_MODE (x)))
&& ((*insn_data[icode].operand[1].predicate)
- (equiv, Pmode))))
+ (equiv, GET_MODE (x)))))
{
/* We use the original pseudo for loc, so that
emit_reload_insns() knows which pseudo this
diff --git a/gcc/reload.h b/gcc/reload.h
index 3789680f7ca..5d8375b9589 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -289,7 +289,7 @@ extern int find_reloads (rtx, int, int, int, short *);
address, namely: sum constant integers, surround the sum of two
constants with a CONST, put the constant as the second operand, and
group the constant on the outermost sum. */
-extern rtx form_sum (rtx, rtx);
+extern rtx form_sum (enum machine_mode, rtx, rtx);
/* Substitute into the current INSN the registers into which we have reloaded
the things that need reloading. */
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 2c881e4d4f0..ce049220608 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -2658,7 +2658,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
&& reg_equiv_constant[REGNO (new0)] != 0)
new0 = reg_equiv_constant[REGNO (new0)];
- new_rtx = form_sum (new0, new1);
+ new_rtx = form_sum (GET_MODE (x), new0, new1);
/* As above, if we are not inside a MEM we do not want to
turn a PLUS into something else. We might try to do so here
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e9536b54536..7cf3a7fe2e0 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1613,7 +1613,10 @@ extern unsigned int subreg_highpart_offset (enum machine_mode,
enum machine_mode);
extern int byte_lowpart_offset (enum machine_mode, enum machine_mode);
extern rtx make_safe_from (rtx, rtx);
-extern rtx convert_memory_address (enum machine_mode, rtx);
+extern rtx convert_memory_address_addr_space (enum machine_mode, rtx,
+ addr_space_t);
+#define convert_memory_address(to_mode,x) \
+ convert_memory_address_addr_space ((to_mode), (x), ADDR_SPACE_GENERIC)
extern rtx get_insns (void);
extern const char *get_insn_name (int);
extern rtx get_last_insn (void);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 7da04f2835a..d14bbe58bf7 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3748,7 +3748,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
/* If pointers extend unsigned and this is a pointer in Pmode, say that
all the bits above ptr_mode are known to be zero. */
- if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+ /* As we do not know which address space the pointer is refering to,
+ we can do this only if the target does not support different pointer
+ or address modes depending on the address space. */
+ if (target_default_pointer_address_modes_p ()
+ && POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
&& REG_POINTER (x))
nonzero &= GET_MODE_MASK (ptr_mode);
#endif
@@ -3985,7 +3989,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
/* If pointers extend unsigned and this is an addition or subtraction
to a pointer in Pmode, all the bits above ptr_mode are known to be
zero. */
- if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
+ /* As we do not know which address space the pointer is refering to,
+ we can do this only if the target does not support different pointer
+ or address modes depending on the address space. */
+ if (target_default_pointer_address_modes_p ()
+ && POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
&& (code == PLUS || code == MINUS)
&& REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
nonzero &= GET_MODE_MASK (ptr_mode);
@@ -4259,8 +4267,12 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
/* If pointers extend signed and this is a pointer in Pmode, say that
all the bits above ptr_mode are known to be sign bit copies. */
- if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
- && REG_POINTER (x))
+ /* As we do not know which address space the pointer is refering to,
+ we can do this only if the target does not support different pointer
+ or address modes depending on the address space. */
+ if (target_default_pointer_address_modes_p ()
+ && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+ && mode == Pmode && REG_POINTER (x))
return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
#endif
@@ -4456,7 +4468,11 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
/* If pointers extend signed and this is an addition or subtraction
to a pointer in Pmode, all the bits above ptr_mode are known to be
sign bit copies. */
- if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+ /* As we do not know which address space the pointer is refering to,
+ we can do this only if the target does not support different pointer
+ or address modes depending on the address space. */
+ if (target_default_pointer_address_modes_p ()
+ && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
&& (code == PLUS || code == MINUS)
&& REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 1fd484d97aa..1f1a76c1090 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "cselib.h"
#include "ira.h"
+#include "target.h"
#ifdef INSN_SCHEDULING
@@ -2281,8 +2282,11 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
if (sched_deps_info->use_cselib)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
+
t = shallow_copy_rtx (dest);
- cselib_lookup (XEXP (t, 0), Pmode, 1);
+ cselib_lookup (XEXP (t, 0), address_mode, 1);
XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
}
t = canon_rtx (t);
@@ -2435,8 +2439,11 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
if (sched_deps_info->use_cselib)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (t));
+
t = shallow_copy_rtx (t);
- cselib_lookup (XEXP (t, 0), Pmode, 1);
+ cselib_lookup (XEXP (t, 0), address_mode, 1);
XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
}
diff --git a/gcc/sel-sched-dump.c b/gcc/sel-sched-dump.c
index 5fce7cf6b9e..b307f52b841 100644
--- a/gcc/sel-sched-dump.c
+++ b/gcc/sel-sched-dump.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "basic-block.h"
#include "cselib.h"
+#include "target.h"
#ifdef INSN_SCHEDULING
#include "sel-sched-ir.h"
@@ -931,10 +932,13 @@ rtx
debug_mem_addr_value (rtx x)
{
rtx t, addr;
+ enum machine_mode address_mode;
gcc_assert (MEM_P (x));
+ address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+
t = shallow_copy_rtx (x);
- if (cselib_lookup (XEXP (t, 0), Pmode, 0))
+ if (cselib_lookup (XEXP (t, 0), address_mode, 0))
XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
t = canon_rtx (t);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 926615ec86f..39a791d9890 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1012,7 +1012,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
return rtl_hooks.gen_lowpart_no_emit (mode, op);
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
- if (! POINTERS_EXTEND_UNSIGNED
+ /* As we do not know which address space the pointer is refering to,
+ we can do this only if the target does not support different pointer
+ or address modes depending on the address space. */
+ if (target_default_pointer_address_modes_p ()
+ && ! POINTERS_EXTEND_UNSIGNED
&& mode == Pmode && GET_MODE (op) == ptr_mode
&& (CONSTANT_P (op)
|| (GET_CODE (op) == SUBREG
@@ -1034,7 +1038,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
return rtl_hooks.gen_lowpart_no_emit (mode, op);
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
- if (POINTERS_EXTEND_UNSIGNED > 0
+ /* As we do not know which address space the pointer is refering to,
+ we can do this only if the target does not support different pointer
+ or address modes depending on the address space. */
+ if (target_default_pointer_address_modes_p ()
+ && POINTERS_EXTEND_UNSIGNED > 0
&& mode == Pmode && GET_MODE (op) == ptr_mode
&& (CONSTANT_P (op)
|| (GET_CODE (op) == SUBREG
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index d070b10e3dc..e512db83979 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -52,9 +52,9 @@ unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNI
/* ... and its original value in bytes, specified via -fpack-struct=<value>. */
unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT;
-/* Nonzero if all REFERENCE_TYPEs are internal and hence should be
- allocated in Pmode, not ptr_mode. Set only by internal_reference_types
- called only by a front end. */
+/* Nonzero if all REFERENCE_TYPEs are internal and hence should be allocated
+ in the address spaces' address_mode, not pointer_mode. Set only by
+ internal_reference_types called only by a front end. */
static int reference_types_internal = 0;
static tree self_referential_size (tree);
@@ -71,8 +71,8 @@ extern void debug_rli (record_layout_info);
static GTY(()) tree pending_sizes;
-/* Show that REFERENCE_TYPES are internal and should be Pmode. Called only
- by front end. */
+/* Show that REFERENCE_TYPES are internal and should use address_mode.
+ Called only by front end. */
void
internal_reference_types (void)
@@ -1917,6 +1917,7 @@ layout_type (tree type)
/* A pointer might be MODE_PARTIAL_INT,
but ptrdiff_t must be integral. */
SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
+ TYPE_PRECISION (type) = POINTER_SIZE;
break;
case FUNCTION_TYPE:
@@ -1932,16 +1933,17 @@ layout_type (tree type)
case POINTER_TYPE:
case REFERENCE_TYPE:
{
- enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
- && reference_types_internal)
- ? Pmode : TYPE_MODE (type));
-
- int nbits = GET_MODE_BITSIZE (mode);
+ enum machine_mode mode = TYPE_MODE (type);
+ if (TREE_CODE (type) == REFERENCE_TYPE && reference_types_internal)
+ {
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+ mode = targetm.addr_space.address_mode (as);
+ }
- TYPE_SIZE (type) = bitsize_int (nbits);
+ TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
TYPE_UNSIGNED (type) = 1;
- TYPE_PRECISION (type) = nbits;
+ TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
}
break;
diff --git a/gcc/target-def.h b/gcc/target-def.h
index fae4210c273..547a5fb89f8 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -471,6 +471,19 @@
#define TARGET_VALID_POINTER_MODE default_valid_pointer_mode
#endif
+#ifndef TARGET_ADDR_SPACE_POINTER_MODE
+#define TARGET_ADDR_SPACE_POINTER_MODE default_addr_space_pointer_mode
+#endif
+
+#ifndef TARGET_ADDR_SPACE_ADDRESS_MODE
+#define TARGET_ADDR_SPACE_ADDRESS_MODE default_addr_space_address_mode
+#endif
+
+#ifndef TARGET_ADDR_SPACE_VALID_POINTER_MODE
+#define TARGET_ADDR_SPACE_VALID_POINTER_MODE \
+ default_addr_space_valid_pointer_mode
+#endif
+
#ifndef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
default_addr_space_legitimate_address_p
@@ -491,6 +504,9 @@
#define TARGET_ADDR_SPACE_HOOKS \
{ \
+ TARGET_ADDR_SPACE_POINTER_MODE, \
+ TARGET_ADDR_SPACE_ADDRESS_MODE, \
+ TARGET_ADDR_SPACE_VALID_POINTER_MODE, \
TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P, \
TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS, \
TARGET_ADDR_SPACE_SUBSET_P, \
diff --git a/gcc/target.h b/gcc/target.h
index 5b296d5df31..a243bcd3bfb 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -68,6 +68,12 @@ typedef int (* print_switch_fn_type) (print_switch_type, const char *);
/* An example implementation for ELF targets. Defined in varasm.c */
extern int elf_record_gcc_switches (print_switch_type type, const char *);
+/* Some places still assume that all pointer or address modes are the
+ standard Pmode and ptr_mode. These optimizations become invalid if
+ the target actually supports multiple different modes. For now,
+ we disable such optimizations on such targets, using this function. */
+extern bool target_default_pointer_address_modes_p (void);
+
struct stdarg_info;
struct spec_info_def;
@@ -696,6 +702,16 @@ struct gcc_target
/* Support for named address spaces. */
struct addr_space {
+ /* MODE to use for a pointer into another address space. */
+ enum machine_mode (* pointer_mode) (addr_space_t);
+
+ /* MODE to use for an address in another address space. */
+ enum machine_mode (* address_mode) (addr_space_t);
+
+ /* True if MODE is valid for a pointer in __attribute__((mode("MODE")))
+ in another address space. */
+ bool (* valid_pointer_mode) (enum machine_mode, addr_space_t);
+
/* True if an address is a valid memory address to a given named address
space for a given mode. */
bool (* legitimate_address_p) (enum machine_mode, rtx, bool, addr_space_t);
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index ab9c05bb029..35ed9eed4a6 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -831,6 +831,62 @@ default_builtin_support_vector_misalignment (enum machine_mode mode,
return false;
}
+/* Determine whether or not a pointer mode is valid. Assume defaults
+ of ptr_mode or Pmode - can be overridden. */
+bool
+default_valid_pointer_mode (enum machine_mode mode)
+{
+ return (mode == ptr_mode || mode == Pmode);
+}
+
+/* Return the mode for a pointer to a given ADDRSPACE, defaulting to ptr_mode
+ for the generic address space only. */
+
+enum machine_mode
+default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
+{
+ gcc_assert (ADDR_SPACE_GENERIC_P (addrspace));
+ return ptr_mode;
+}
+
+/* Return the mode for an address in a given ADDRSPACE, defaulting to Pmode
+ for the generic address space only. */
+
+enum machine_mode
+default_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
+{
+ gcc_assert (ADDR_SPACE_GENERIC_P (addrspace));
+ return Pmode;
+}
+
+/* Named address space version of valid_pointer_mode. */
+
+bool
+default_addr_space_valid_pointer_mode (enum machine_mode mode, addr_space_t as)
+{
+ if (!ADDR_SPACE_GENERIC_P (as))
+ return (mode == targetm.addr_space.pointer_mode (as)
+ || mode == targetm.addr_space.address_mode (as));
+
+ return targetm.valid_pointer_mode (mode);
+}
+
+/* Some places still assume that all pointer or address modes are the
+ standard Pmode and ptr_mode. These optimizations become invalid if
+ the target actually supports multiple different modes. For now,
+ we disable such optimizations on such targets, using this function. */
+
+bool
+target_default_pointer_address_modes_p (void)
+{
+ if (targetm.addr_space.address_mode != default_addr_space_address_mode)
+ return false;
+ if (targetm.addr_space.pointer_mode != default_addr_space_pointer_mode)
+ return false;
+
+ return true;
+}
+
/* Named address space version of legitimate_address_p. */
bool
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index eedc52b0ae7..cbbbee89d2e 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -119,6 +119,11 @@ extern bool default_hard_regno_scratch_ok (unsigned int);
extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
extern bool default_target_option_pragma_parse (tree, tree);
extern bool default_target_can_inline_p (tree, tree);
+extern bool default_valid_pointer_mode (enum machine_mode);
+extern enum machine_mode default_addr_space_pointer_mode (addr_space_t);
+extern enum machine_mode default_addr_space_address_mode (addr_space_t);
+extern bool default_addr_space_valid_pointer_mode (enum machine_mode,
+ addr_space_t);
extern bool default_addr_space_legitimate_address_p (enum machine_mode, rtx,
bool, addr_space_t);
extern rtx default_addr_space_legitimize_address (rtx, rtx, enum machine_mode,
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index ca1e06a0b62..a7015691811 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -922,7 +922,7 @@ struct mem_address
struct affine_tree_combination;
tree create_mem_ref (gimple_stmt_iterator *, tree,
struct affine_tree_combination *, bool);
-rtx addr_for_mem_ref (struct mem_address *, bool);
+rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
void get_address_description (tree, struct mem_address *);
tree maybe_fold_tmr (tree);
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index c5e34229bf6..1428803272f 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "ggc.h"
#include "tree-affine.h"
+#include "target.h"
/* TODO -- handling of symbols (according to Richard Hendersons
comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
@@ -70,32 +71,38 @@ along with GCC; see the file COPYING3. If not see
/* A "template" for memory address, used to determine whether the address is
valid for mode. */
-struct GTY (()) mem_addr_template {
+typedef struct GTY (()) mem_addr_template {
rtx ref; /* The template. */
rtx * GTY ((skip)) step_p; /* The point in template where the step should be
filled in. */
rtx * GTY ((skip)) off_p; /* The point in template where the offset should
be filled in. */
-};
+} mem_addr_template;
-/* The templates. Each of the five bits of the index corresponds to one
- component of TARGET_MEM_REF being present, see TEMPL_IDX. */
+DEF_VEC_O (mem_addr_template);
+DEF_VEC_ALLOC_O (mem_addr_template, gc);
-static GTY (()) struct mem_addr_template templates[32];
+/* The templates. Each of the low five bits of the index corresponds to one
+ component of TARGET_MEM_REF being present, while the high bits identify
+ the address space. See TEMPL_IDX. */
-#define TEMPL_IDX(SYMBOL, BASE, INDEX, STEP, OFFSET) \
- (((SYMBOL != 0) << 4) \
+static GTY(()) VEC (mem_addr_template, gc) *mem_addr_template_list;
+
+#define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
+ (((int) (AS) << 5) \
+ | ((SYMBOL != 0) << 4) \
| ((BASE != 0) << 3) \
| ((INDEX != 0) << 2) \
| ((STEP != 0) << 1) \
| (OFFSET != 0))
/* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
- STEP and OFFSET to *ADDR. Stores pointers to where step is placed to
- *STEP_P and offset to *OFFSET_P. */
+ STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers
+ to where step is placed to *STEP_P and offset to *OFFSET_P. */
static void
-gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
+gen_addr_rtx (enum machine_mode address_mode,
+ rtx symbol, rtx base, rtx index, rtx step, rtx offset,
rtx *addr, rtx **step_p, rtx **offset_p)
{
rtx act_elem;
@@ -111,7 +118,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
act_elem = index;
if (step)
{
- act_elem = gen_rtx_MULT (Pmode, act_elem, step);
+ act_elem = gen_rtx_MULT (address_mode, act_elem, step);
if (step_p)
*step_p = &XEXP (act_elem, 1);
@@ -123,7 +130,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
if (base)
{
if (*addr)
- *addr = simplify_gen_binary (PLUS, Pmode, base, *addr);
+ *addr = simplify_gen_binary (PLUS, address_mode, base, *addr);
else
*addr = base;
}
@@ -133,7 +140,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
act_elem = symbol;
if (offset)
{
- act_elem = gen_rtx_PLUS (Pmode, act_elem, offset);
+ act_elem = gen_rtx_PLUS (address_mode, act_elem, offset);
if (offset_p)
*offset_p = &XEXP (act_elem, 1);
@@ -141,11 +148,11 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
if (GET_CODE (symbol) == SYMBOL_REF
|| GET_CODE (symbol) == LABEL_REF
|| GET_CODE (symbol) == CONST)
- act_elem = gen_rtx_CONST (Pmode, act_elem);
+ act_elem = gen_rtx_CONST (address_mode, act_elem);
}
if (*addr)
- *addr = gen_rtx_PLUS (Pmode, *addr, act_elem);
+ *addr = gen_rtx_PLUS (address_mode, *addr, act_elem);
else
*addr = act_elem;
}
@@ -153,7 +160,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
{
if (*addr)
{
- *addr = gen_rtx_PLUS (Pmode, *addr, offset);
+ *addr = gen_rtx_PLUS (address_mode, *addr, offset);
if (offset_p)
*offset_p = &XEXP (*addr, 1);
}
@@ -169,55 +176,64 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
*addr = const0_rtx;
}
-/* Returns address for TARGET_MEM_REF with parameters given by ADDR.
+/* Returns address for TARGET_MEM_REF with parameters given by ADDR
+ in address space AS.
If REALLY_EXPAND is false, just make fake registers instead
of really expanding the operands, and perform the expansion in-place
by using one of the "templates". */
rtx
-addr_for_mem_ref (struct mem_address *addr, bool really_expand)
+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);
rtx address, sym, bse, idx, st, off;
- static bool templates_initialized = false;
struct mem_addr_template *templ;
if (addr->step && !integer_onep (addr->step))
st = immed_double_const (TREE_INT_CST_LOW (addr->step),
- TREE_INT_CST_HIGH (addr->step), Pmode);
+ TREE_INT_CST_HIGH (addr->step), address_mode);
else
st = NULL_RTX;
if (addr->offset && !integer_zerop (addr->offset))
off = immed_double_const (TREE_INT_CST_LOW (addr->offset),
- TREE_INT_CST_HIGH (addr->offset), Pmode);
+ TREE_INT_CST_HIGH (addr->offset), address_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. */
- if (!templates_initialized)
+ templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index);
+ if (!templ->ref)
{
- unsigned i;
-
- templates_initialized = true;
- sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup ("test_symbol"));
- bse = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
- idx = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2);
-
- for (i = 0; i < 32; i++)
- gen_addr_rtx ((i & 16 ? sym : NULL_RTX),
- (i & 8 ? bse : NULL_RTX),
- (i & 4 ? idx : NULL_RTX),
- (i & 2 ? const0_rtx : NULL_RTX),
- (i & 1 ? const0_rtx : NULL_RTX),
- &templates[i].ref,
- &templates[i].step_p,
- &templates[i].off_p);
+ sym = (addr->symbol ?
+ gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol"))
+ : NULL_RTX);
+ bse = (addr->base ?
+ gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1)
+ : NULL_RTX);
+ idx = (addr->index ?
+ gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2)
+ : NULL_RTX);
+
+ gen_addr_rtx (address_mode, sym, bse, idx,
+ st? const0_rtx : NULL_RTX,
+ off? const0_rtx : NULL_RTX,
+ &templ->ref,
+ &templ->step_p,
+ &templ->off_p);
}
- templ = templates + TEMPL_IDX (addr->symbol, addr->base, addr->index,
- st, off);
if (st)
*templ->step_p = st;
if (off)
@@ -229,16 +245,16 @@ addr_for_mem_ref (struct mem_address *addr, bool really_expand)
/* Otherwise really expand the expressions. */
sym = (addr->symbol
? expand_expr (build_addr (addr->symbol, current_function_decl),
- NULL_RTX, Pmode, EXPAND_NORMAL)
+ NULL_RTX, address_mode, EXPAND_NORMAL)
: NULL_RTX);
bse = (addr->base
- ? expand_expr (addr->base, NULL_RTX, Pmode, EXPAND_NORMAL)
+ ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL)
: NULL_RTX);
idx = (addr->index
- ? expand_expr (addr->index, NULL_RTX, Pmode, EXPAND_NORMAL)
+ ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL)
: NULL_RTX);
- gen_addr_rtx (sym, bse, idx, st, off, &address, NULL, NULL);
+ gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL);
return address;
}
@@ -310,7 +326,7 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as,
{
rtx address;
- address = addr_for_mem_ref (addr, false);
+ address = addr_for_mem_ref (addr, as, false);
if (!address)
return false;
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 7e536136c80..82e45d2db4d 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2643,13 +2643,14 @@ static rtx
produce_memory_decl_rtl (tree obj, int *regno)
{
addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (obj));
+ enum machine_mode address_mode = targetm.addr_space.address_mode (as);
rtx x;
gcc_assert (obj);
if (TREE_STATIC (obj) || DECL_EXTERNAL (obj))
{
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));
- x = gen_rtx_SYMBOL_REF (Pmode, name);
+ x = gen_rtx_SYMBOL_REF (address_mode, name);
SET_SYMBOL_REF_DECL (x, obj);
x = gen_rtx_MEM (DECL_MODE (obj), x);
set_mem_addr_space (x, as);
@@ -2657,7 +2658,7 @@ produce_memory_decl_rtl (tree obj, int *regno)
}
else
{
- x = gen_raw_REG (Pmode, (*regno)++);
+ x = gen_raw_REG (address_mode, (*regno)++);
x = gen_rtx_MEM (DECL_MODE (obj), x);
set_mem_addr_space (x, as);
}
@@ -3045,16 +3046,17 @@ multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, enum machine_mode mode,
valid_mult = VEC_index (sbitmap, valid_mult_list, data_index);
if (!valid_mult)
{
- rtx reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
+ enum machine_mode address_mode = targetm.addr_space.address_mode (as);
+ rtx reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
rtx addr;
HOST_WIDE_INT i;
valid_mult = sbitmap_alloc (2 * MAX_RATIO + 1);
sbitmap_zero (valid_mult);
- addr = gen_rtx_fmt_ee (MULT, Pmode, reg1, NULL_RTX);
+ addr = gen_rtx_fmt_ee (MULT, address_mode, reg1, NULL_RTX);
for (i = -MAX_RATIO; i <= MAX_RATIO; i++)
{
- XEXP (addr, 1) = gen_int_mode (i, Pmode);
+ XEXP (addr, 1) = gen_int_mode (i, address_mode);
if (memory_address_addr_space_p (mode, addr, as))
SET_BIT (valid_mult, i + MAX_RATIO);
}
@@ -3108,6 +3110,7 @@ get_address_cost (bool symbol_present, bool var_present,
addr_space_t as, bool speed,
bool stmt_after_inc, bool *may_autoinc)
{
+ enum machine_mode address_mode = targetm.addr_space.address_mode (as);
static VEC(address_cost_data, heap) *address_cost_data_list;
unsigned int data_index = (int) as * MAX_MACHINE_MODE + (int) mem_mode;
address_cost_data data;
@@ -3136,12 +3139,12 @@ get_address_cost (bool symbol_present, bool var_present,
data = (address_cost_data) xcalloc (1, sizeof (*data));
- reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
+ reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
- addr = gen_rtx_fmt_ee (PLUS, Pmode, reg1, NULL_RTX);
+ addr = gen_rtx_fmt_ee (PLUS, address_mode, reg1, NULL_RTX);
for (i = start; i <= 1 << 20; i <<= 1)
{
- XEXP (addr, 1) = gen_int_mode (i, Pmode);
+ XEXP (addr, 1) = gen_int_mode (i, address_mode);
if (!memory_address_addr_space_p (mem_mode, addr, as))
break;
}
@@ -3150,7 +3153,7 @@ get_address_cost (bool symbol_present, bool var_present,
for (i = start; i <= 1 << 20; i <<= 1)
{
- XEXP (addr, 1) = gen_int_mode (-i, Pmode);
+ XEXP (addr, 1) = gen_int_mode (-i, address_mode);
if (!memory_address_addr_space_p (mem_mode, addr, as))
break;
}
@@ -3177,30 +3180,30 @@ get_address_cost (bool symbol_present, bool var_present,
/* Compute the cost of various addressing modes. */
acost = 0;
- reg0 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
- reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2);
+ reg0 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
+ reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2);
if (HAVE_PRE_DECREMENT)
{
- addr = gen_rtx_PRE_DEC (Pmode, reg0);
+ addr = gen_rtx_PRE_DEC (address_mode, reg0);
has_predec[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
if (HAVE_POST_DECREMENT)
{
- addr = gen_rtx_POST_DEC (Pmode, reg0);
+ addr = gen_rtx_POST_DEC (address_mode, reg0);
has_postdec[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
if (HAVE_PRE_INCREMENT)
{
- addr = gen_rtx_PRE_INC (Pmode, reg0);
+ addr = gen_rtx_PRE_INC (address_mode, reg0);
has_preinc[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
if (HAVE_POST_INCREMENT)
{
- addr = gen_rtx_POST_INC (Pmode, reg0);
+ addr = gen_rtx_POST_INC (address_mode, reg0);
has_postinc[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
@@ -3213,15 +3216,15 @@ get_address_cost (bool symbol_present, bool var_present,
addr = reg0;
if (rat_p)
- addr = gen_rtx_fmt_ee (MULT, Pmode, addr,
- gen_int_mode (rat, Pmode));
+ addr = gen_rtx_fmt_ee (MULT, address_mode, addr,
+ gen_int_mode (rat, address_mode));
if (var_p)
- addr = gen_rtx_fmt_ee (PLUS, Pmode, addr, reg1);
+ addr = gen_rtx_fmt_ee (PLUS, address_mode, addr, reg1);
if (sym_p)
{
- base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (""));
+ base = gen_rtx_SYMBOL_REF (address_mode, ggc_strdup (""));
/* ??? We can run into trouble with some backends by presenting
it with symbols which haven't been properly passed through
targetm.encode_section_info. By setting the local bit, we
@@ -3229,18 +3232,18 @@ get_address_cost (bool symbol_present, bool var_present,
SYMBOL_REF_FLAGS (base) = SYMBOL_FLAG_LOCAL;
if (off_p)
- base = gen_rtx_fmt_e (CONST, Pmode,
+ base = gen_rtx_fmt_e (CONST, address_mode,
gen_rtx_fmt_ee
- (PLUS, Pmode, base,
- gen_int_mode (off, Pmode)));
+ (PLUS, address_mode, base,
+ gen_int_mode (off, address_mode)));
}
else if (off_p)
- base = gen_int_mode (off, Pmode);
+ base = gen_int_mode (off, address_mode);
else
base = NULL_RTX;
if (base)
- addr = gen_rtx_fmt_ee (PLUS, Pmode, addr, base);
+ addr = gen_rtx_fmt_ee (PLUS, address_mode, addr, base);
start_sequence ();
/* To avoid splitting addressing modes, pretend that no cse will
@@ -3272,7 +3275,7 @@ get_address_cost (bool symbol_present, bool var_present,
If VAR_PRESENT is true, try whether the mode with
SYMBOL_PRESENT = false is cheaper even with cost of addition, and
if this is the case, use it. */
- add_c = add_cost (Pmode, speed);
+ add_c = add_cost (address_mode, speed);
for (i = 0; i < 8; i++)
{
var_p = i & 1;
@@ -3321,7 +3324,7 @@ get_address_cost (bool symbol_present, bool var_present,
data_index, data);
}
- bits = GET_MODE_BITSIZE (Pmode);
+ bits = GET_MODE_BITSIZE (address_mode);
mask = ~(~(unsigned HOST_WIDE_INT) 0 << (bits - 1) << 1);
offset &= mask;
if ((offset >> (bits - 1) & 1))
@@ -3353,10 +3356,10 @@ get_address_cost (bool symbol_present, bool var_present,
&& multiplier_allowed_in_address_p (ratio, mem_mode, as));
if (ratio != 1 && !ratio_p)
- cost += multiply_by_cost (ratio, Pmode, speed);
+ cost += multiply_by_cost (ratio, address_mode, speed);
if (s_offset && !offset_p && !symbol_present)
- cost += add_cost (Pmode, speed);
+ cost += add_cost (address_mode, speed);
if (may_autoinc)
*may_autoinc = autoinc;
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index c3570d31948..ea3a508966f 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -2376,7 +2376,9 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
if (!alias_sets_conflict_p (get_deref_alias_set (vect_ptr),
get_alias_set (DR_REF (dr))))
{
- vect_ptr_type = build_pointer_type_for_mode (vectype, ptr_mode, true);
+ vect_ptr_type
+ = build_pointer_type_for_mode (vectype,
+ TYPE_MODE (vect_ptr_type), true);
vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
get_name (base_name));
}
@@ -2392,7 +2394,8 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
get_alias_set (lhs)))
{
vect_ptr_type
- = build_pointer_type_for_mode (vectype, ptr_mode, true);
+ = build_pointer_type_for_mode (vectype,
+ TYPE_MODE (vect_ptr_type), true);
vect_ptr
= vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
get_name (base_name));
diff --git a/gcc/tree.c b/gcc/tree.c
index dfc88077e96..43434150231 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1684,8 +1684,7 @@ integer_pow2p (const_tree expr)
if (TREE_CODE (expr) != INTEGER_CST)
return 0;
- prec = (POINTER_TYPE_P (TREE_TYPE (expr))
- ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
+ prec = int_or_pointer_precision (TREE_TYPE (expr));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
@@ -1749,9 +1748,7 @@ tree_log2 (const_tree expr)
if (TREE_CODE (expr) == COMPLEX_CST)
return tree_log2 (TREE_REALPART (expr));
- prec = (POINTER_TYPE_P (TREE_TYPE (expr))
- ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
-
+ prec = int_or_pointer_precision (TREE_TYPE (expr));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
@@ -1787,9 +1784,7 @@ tree_floor_log2 (const_tree expr)
if (TREE_CODE (expr) == COMPLEX_CST)
return tree_log2 (TREE_REALPART (expr));
- prec = (POINTER_TYPE_P (TREE_TYPE (expr))
- ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
-
+ prec = int_or_pointer_precision (TREE_TYPE (expr));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
@@ -6746,7 +6741,10 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
tree
build_pointer_type (tree to_type)
{
- return build_pointer_type_for_mode (to_type, ptr_mode, false);
+ addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
+ : TYPE_ADDR_SPACE (to_type);
+ enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+ return build_pointer_type_for_mode (to_type, pointer_mode, false);
}
/* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE. */
@@ -6810,7 +6808,10 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode,
tree
build_reference_type (tree to_type)
{
- return build_reference_type_for_mode (to_type, ptr_mode, false);
+ addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
+ : TYPE_ADDR_SPACE (to_type);
+ enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+ return build_reference_type_for_mode (to_type, pointer_mode, false);
}
/* Build a type that is compatible with t but has no cv quals anywhere
@@ -9675,7 +9676,19 @@ signed_or_unsigned_type_for (int unsignedp, tree type)
{
tree t = type;
if (POINTER_TYPE_P (type))
- t = size_type_node;
+ {
+ /* If the pointer points to the normal address space, use the
+ size_type_node. Otherwise use an appropriate size for the pointer
+ based on the named address space it points to. */
+ if (!TYPE_ADDR_SPACE (TREE_TYPE (t)))
+ t = size_type_node;
+
+ else
+ {
+ int prec = int_or_pointer_precision (t);
+ return lang_hooks.types.type_for_size (prec, unsignedp);
+ }
+ }
if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
return t;
@@ -10549,6 +10562,41 @@ build_target_option_node (void)
return t;
}
+/* Return the size in bits of an integer or pointer type. TYPE_PRECISION
+ contains the bits, but in the past it was not set in some cases and there
+ was special purpose code that checked for POINTER_TYPE_P or OFFSET_TYPE, so
+ check that it is consitant when assertion checking is used. */
+
+unsigned int
+int_or_pointer_precision (const_tree type)
+{
+#if ENABLE_ASSERT_CHECKING
+ unsigned int prec;
+
+ if (POINTER_TYPE_P (type))
+ {
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+ prec = GET_MODE_BITSIZE (targetm.addr_space.pointer_mode (as));
+ gcc_assert (prec == TYPE_PRECISION (type));
+ }
+ else if (TREE_CODE (type) == OFFSET_TYPE)
+ {
+ prec = POINTER_SIZE;
+ gcc_assert (prec == TYPE_PRECISION (type));
+ }
+ else
+ {
+ prec = TYPE_PRECISION (type);
+ gcc_assert (prec != 0);
+ }
+
+ return prec;
+
+#else
+ return TYPE_PRECISION (type);
+#endif
+}
+
/* Determine the "ultimate origin" of a block. The block may be an inlined
instance of an inlined instance of a block which is local to an inline
function, so we have to trace all of the way back through the origin chain
diff --git a/gcc/tree.h b/gcc/tree.h
index ad810b040c5..36deb0d51e5 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4703,6 +4703,7 @@ extern const char *get_name (tree);
extern bool stdarg_p (tree);
extern bool prototype_p (tree);
extern bool auto_var_in_fn_p (const_tree, const_tree);
+extern unsigned int int_or_pointer_precision (const_tree);
extern tree build_low_bits_mask (tree, unsigned);
extern tree tree_strip_nop_conversions (tree);
extern tree tree_strip_sign_nop_conversions (tree);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index cfcc839b96c..9fa19219186 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -4359,7 +4359,9 @@ replace_expr_with_values (rtx loc)
return NULL;
else if (MEM_P (loc))
{
- cselib_val *addr = cselib_lookup (XEXP (loc, 0), Pmode, 0);
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (loc));
+ cselib_val *addr = cselib_lookup (XEXP (loc, 0), address_mode, 0);
if (addr)
return replace_equiv_address_nv (loc, addr->val_rtx);
else
@@ -4493,7 +4495,9 @@ count_uses (rtx *loc, void *cuip)
if (MEM_P (*loc)
&& !REG_P (XEXP (*loc, 0)) && !MEM_P (XEXP (*loc, 0)))
{
- val = cselib_lookup (XEXP (*loc, 0), Pmode, false);
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (*loc));
+ val = cselib_lookup (XEXP (*loc, 0), address_mode, false);
if (val && !cselib_preserved_value_p (val))
{
@@ -4613,7 +4617,10 @@ add_uses (rtx *loc, void *data)
&& !REG_P (XEXP (vloc, 0)) && !MEM_P (XEXP (vloc, 0)))
{
rtx mloc = vloc;
- cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
+ cselib_val *val
+ = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
if (val && !cselib_preserved_value_p (val))
{
@@ -4624,7 +4631,8 @@ add_uses (rtx *loc, void *data)
cselib_preserve_value (val);
mo->type = MO_VAL_USE;
mloc = cselib_subst_to_values (XEXP (mloc, 0));
- mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
+ mo->u.loc = gen_rtx_CONCAT (address_mode,
+ val->val_rtx, mloc);
if (dump_file && (dump_flags & TDF_DETAILS))
log_op_type (mo->u.loc, cui->bb, cui->insn,
mo->type, dump_file);
@@ -4680,7 +4688,10 @@ add_uses (rtx *loc, void *data)
&& !REG_P (XEXP (oloc, 0)) && !MEM_P (XEXP (oloc, 0)))
{
rtx mloc = oloc;
- cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
+ cselib_val *val
+ = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
if (val && !cselib_preserved_value_p (val))
{
@@ -4691,7 +4702,8 @@ add_uses (rtx *loc, void *data)
cselib_preserve_value (val);
mo->type = MO_VAL_USE;
mloc = cselib_subst_to_values (XEXP (mloc, 0));
- mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
+ mo->u.loc = gen_rtx_CONCAT (address_mode,
+ val->val_rtx, mloc);
mo->insn = cui->insn;
if (dump_file && (dump_flags & TDF_DETAILS))
log_op_type (mo->u.loc, cui->bb, cui->insn,
@@ -4824,14 +4836,16 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
&& !REG_P (XEXP (loc, 0)) && !MEM_P (XEXP (loc, 0)))
{
rtx mloc = loc;
- cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
+ cselib_val *val = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
if (val && !cselib_preserved_value_p (val))
{
cselib_preserve_value (val);
mo->type = MO_VAL_USE;
mloc = cselib_subst_to_values (XEXP (mloc, 0));
- mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
+ mo->u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc);
mo->insn = cui->insn;
if (dump_file && (dump_flags & TDF_DETAILS))
log_op_type (mo->u.loc, cui->bb, cui->insn,
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 95239b2d432..b6ff4ae149d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1447,7 +1447,15 @@ make_decl_rtl (tree decl)
if (use_object_blocks_p () && use_blocks_for_decl_p (decl))
x = create_block_symbol (name, get_block_for_decl (decl), -1);
else
- x = gen_rtx_SYMBOL_REF (Pmode, name);
+ {
+ enum machine_mode address_mode = Pmode;
+ if (TREE_TYPE (decl) != error_mark_node)
+ {
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
+ address_mode = targetm.addr_space.address_mode (as);
+ }
+ x = gen_rtx_SYMBOL_REF (address_mode, name);
+ }
SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
SET_SYMBOL_REF_DECL (x, decl);
@@ -4315,7 +4323,8 @@ initializer_constant_valid_p (tree value, tree endtype)
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
if (! INTEGRAL_TYPE_P (endtype)
- || TYPE_PRECISION (endtype) >= POINTER_SIZE)
+ || TYPE_PRECISION (endtype)
+ >= int_or_pointer_precision (TREE_TYPE (value)))
{
tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
endtype);
@@ -4337,7 +4346,8 @@ initializer_constant_valid_p (tree value, tree endtype)
case MINUS_EXPR:
if (! INTEGRAL_TYPE_P (endtype)
- || TYPE_PRECISION (endtype) >= POINTER_SIZE)
+ || TYPE_PRECISION (endtype)
+ >= int_or_pointer_precision (TREE_TYPE (value)))
{
tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
endtype);
@@ -4458,7 +4468,9 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
resolving it. */
if (TREE_CODE (exp) == NOP_EXPR
&& POINTER_TYPE_P (TREE_TYPE (exp))
- && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+ && targetm.addr_space.valid_pointer_mode
+ (TYPE_MODE (TREE_TYPE (exp)),
+ TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)))))
{
tree saved_type = TREE_TYPE (exp);
@@ -4466,7 +4478,9 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
pointer modes. */
while (TREE_CODE (exp) == NOP_EXPR
&& POINTER_TYPE_P (TREE_TYPE (exp))
- && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+ && targetm.addr_space.valid_pointer_mode
+ (TYPE_MODE (TREE_TYPE (exp)),
+ TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)))))
exp = TREE_OPERAND (exp, 0);
/* If what we're left with is the address of something, we can
@@ -6562,14 +6576,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
return local_p;
}
-/* Determine whether or not a pointer mode is valid. Assume defaults
- of ptr_mode or Pmode - can be overridden. */
-bool
-default_valid_pointer_mode (enum machine_mode mode)
-{
- return (mode == ptr_mode || mode == Pmode);
-}
-
/* Default function to output code that will globalize a label. A
target must define GLOBAL_ASM_OP or provide its own function to
globalize a label. */