From: Ben Elliston Date: Mon, 26 Oct 2009 21:57:10 +0000 (+0000) Subject: tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document. X-Git-Tag: releases/gcc-4.5.0~2697 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d4ebfa65c962f1f0b50223e34184dc5a81d907c6;p=thirdparty%2Fgcc.git tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document. 2009-10-26 Ben Elliston Michael Meissner Ulrich Weigand * 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 Co-Authored-By: Ulrich Weigand From-SVN: r153573 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ebe6aec2ba44..658274da3038 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,140 @@ +2009-10-26 Ben Elliston + Michael Meissner + Ulrich Weigand + + * 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 Michael Meissner Ulrich Weigand diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 934c4ed1b3a9..5dd47e57f399 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 b6d0b7eccc59..40226f26b171 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 929a2dcade85..3b3006c985fa 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 21b900a540a2..fdc4de586ef7 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 89dc41549472..2311755691cf 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 7065429be8b8..0aa22a4fe1b0 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 4a2fe56df951..26b5a14a3d78 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 f11c34a6c4c8..a883bcd3d693 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 baad4a85eefb..d7600bccc26b 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 1115f222c4c2..c38682d4ce5e 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 98a99a2b5f1c..12370d073335 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 5e8fae123cb2..e62b53021148 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 aab4fac9edbe..102929d1e20f 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 8b1b4500e6f5..d8d15a59be1e 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 9e2b704920a2..5d771d7d06f5 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 893751886ebc..ac8350d1f4e2 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 4d45d5d1beb9..581af4c7edca 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 166bcb986116..3333697f2e06 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 3789680f7cad..5d8375b9589c 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 2c881e4d4f0e..ce0492206088 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 e9536b54536f..7cf3a7fe2e01 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 7da04f2835ad..d14bbe58bf75 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 1fd484d97aab..1f1a76c10901 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 5fce7cf6b9e8..b307f52b8414 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 926615ec86f2..39a791d98908 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 d070b10e3dcc..e512db839793 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=. */ 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 fae4210c2736..547a5fb89f8a 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 5b296d5df310..a243bcd3bfbd 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 ab9c05bb0297..35ed9eed4a6f 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 eedc52b0ae79..cbbbee89d2ef 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 ca1e06a0b628..a70156918118 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 c5e34229bf6b..1428803272f3 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 7e536136c806..82e45d2db4d3 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 c3570d31948b..ea3a508966f8 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 dfc88077e962..43434150231c 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 ad810b040c58..36deb0d51e58 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 cfcc839b96c8..9fa192191861 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 95239b2d4321..b6ff4ae149dd 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. */