tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.

2009-10-26  Ben Elliston  <bje@au.ibm.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>
	    Ulrich Weigand  <uweigand@de.ibm.com>

	* doc/tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.
	(TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
	(TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.

	* target.h (struct target_def): Add pointer_mode, address_mode,
	and valid_pointer_mode to addr_space substructure.
	* target-def.h (TARGET_ADDR_SPACE_POINTER_MODE): Define.
	(TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
	(TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
	(TARGET_ADDR_SPACE_HOOKS): Add them.
	* targhooks.c (target_default_pointer_address_modes_p): New function.
	* target.h (target_default_pointer_address_modes_p): Add prototype.
	* targhooks.c (default_addr_space_pointer_mode): New function.
	(default_addr_space_address_mode): Likewise.
	(default_addr_space_valid_pointer_mode): Likewise.
	* targhooks.h (default_addr_space_pointer_mode): Add prototype.
	(default_addr_space_address_mode): Likewise.
	(default_addr_space_valid_pointer_mode): Likewise.
	* output.h (default_valid_pointer_mode): Move to ...
	* targhooks.h (default_valid_pointer_mode): ... here.
	* varasm.c (default_valid_pointer_mode): Move to ...
	* targhooks.c (default_valid_pointer_mode): ... here.

	* varasm.c (output_constant): Use targetm.addr_space.valid_pointer_mode
	instead of targetm.valid_pointer_mode.

	* fold-const.c (fit_double_type): Use int_or_pointer_precision.
	* tree.c (integer_pow2p): Likewise.
	(tree_log2): Likewise.
	(tree_floor_log2): Likewise.
	(signed_or_unsigned_type_for): Support pointer type of different size.
	(int_or_pointer_precision): New function.
	* tree.h (int_or_pointer_precision): Add prototype.
	* stor-layout.c (layout_type): Set TYPE_PRECISION for offset types.
	* varasm.c (initializer_constant_valid_p): Use TYPE_PRECISION of
	incoming pointer type instead of POINTER_SIZE.

	* tree.c (build_pointer_type): Use appropriate pointer mode
	instead of ptr_mode.
	(build_reference_type): Likewise.
	* expr.c (store_expr): Likewise.
	(expand_expr_addr_expr): Likewise.
	* tree-vect-data-refs.c (vect_create_data_ref_ptr): Likewise.
	* cfgexpand.c (expand_debug_expr): Likewise.
	
	* auto-inc-dec.c: Include "target.h".
	(try_merge): Use appropriate address mode instead of Pmode.
	(find_inc): Likewise.
	* combine.c (find_split_point): Likewise.
	* cselib.c (cselib_record_sets): Likewise.
	* dse.c (replace_inc_dec): Likewise.
	(canon_address): Likewise.
	* var-tracking.c (replace_expr_with_values): Likewise.
	(count_uses): Likewise.
	(add_uses): Likewise.
	(add_stores): Likewise.
	* emit-rtl.c: Include "target.h".
	(adjust_address_1): Use appropriate address mode instead of Pmode.
	(offset_address): Likewise.
	* explow.c (break_out_memory_refs): Likewise.
	(memory_address_addr_space): Likewise.
	(promote_mode): Likewise.
	* expr.c (move_by_pieces): Likewise.
	(emit_block_move_via_loop): Likewise.
	(store_by_pieces): Likewise.
	(store_by_pieces_1): Likewise.
	(expand_assignment): Likewise.
	(store_constructor): Likewise.
	(expand_expr_addr_expr): Likewise.
	(expand_expr_real_1): Likewise.
	* cfgexpand.c (expand_debug_expr): Likewise.
	* ifcvt.c (noce_try_cmove_arith): Likewise.
	* regcprop.c (kill_autoinc_value): Likewise.
	* regmove.c (try_auto_increment): Likewise.
	* reload.c (find_reloads): Likewise.
	(find_reloads_address): Likewise.
	(find_reloads_address_1): Likewise.
	* sched-deps.c: Include "target.h".
	(sched_analyze_1): Use appropriate address mode instead of Pmode.
	(sched_analyze_2): Likewise.
	* sel-sched-dump.c: Include "target.h".
	(debug_mem_addr_value): Use appropriate address mode instead of Pmode.
	* stor-layout.c (layout_type): Likewise.
	* tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Likewise.
	(multiplier_allowed_in_address_p): Likewise.
	(get_address_cost): Likewise.
	* varasm.c (make_decl_rtl): Likewise.
	
	* expr.c (expand_assignment): Always convert offsets to appropriate
	address mode.
	(store_expr): Likewise.
	(store_constructor): Likewise.
	(expand_expr_real_1): Likewise.

	* reload.h (form_sum): Add MODE argument.
	* reload.c (form_sum): Add MODE argument, use it instead of Pmode.
	Update recursive calls.
	(subst_indexed_address): Update calls to form_sum.
	
	* tree-flow.h (addr_for_mem_ref): Add ADDRSPACE argument.
	* tree-ssa-address.c: Include "target.h".
	(templates): Replace by ...
	(mem_addr_template_list): ... this new vector.
	(TEMPL_IDX): Handle address space numbers.
	(gen_addr_rtx): Add address mode argument, use it instead of Pmode.
	(addr_for_mem_ref): Add ADDRSPACE argument.  Use per-address-space
	instead of global cache.  Update call to gen_addr_rtx.
	(valid_mem_ref_p): Update call to addr_for_mem_ref.
	* expr.c (expand_expr_real_1): Update call to addr_for_mem_ref.
	
	* rtl.h (convert_memory_address_addr_space): Add prototype.
	(convert_memory_address): Define as macro.
	* explow.c (convert_memory_address): Rename to ...
	(convert_memory_address_addr_space): ... this.  Add ADDRSPACE argument.
	Use appropriate pointer and address modes instead of ptr_mode / Pmode.
	Update recursive calls.
	(memory_address_addr_space): Call convert_memory_address_addr_space.
	* expmed.c (make_tree): Likewise.
	* expr.c (expand_assignment): Likewise.
	(expand_expr_addr_expr_1): Likewise.  Also, add ADDRSPACE argument.
	(expand_expr_addr_expr): Likewise.  Also, update call.

	* alias.c (find_base_value): Guard pointer size optimizations.
	(find_base_term): Likewise.
	* rtlanal.c (nonzero_bits1): Likewise.
	(num_sign_bit_copies1): Likewise.
	* simplify-rtx.c (simplify_unary_operation_1): Likewise.

	* Makefile.in (tree-ssa-address.o): Add $(TARGET_H) dependency.
	(emit-rtl.o): Likewise.
	(auto-inc-dec.o): Likewise.
	(sched-deps.o): Likewise.

Co-Authored-By: Michael Meissner <meissner@linux.vnet.ibm.com>
Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com>

From-SVN: r153573
This commit is contained in:
Ben Elliston 2009-10-26 21:57:10 +00:00 committed by Ulrich Weigand
parent 09e881c9e2
commit d4ebfa65c9
39 changed files with 755 additions and 275 deletions

View File

@ -1,3 +1,140 @@
2009-10-26 Ben Elliston <bje@au.ibm.com>
Michael Meissner <meissner@linux.vnet.ibm.com>
Ulrich Weigand <uweigand@de.ibm.com>
* doc/tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.
(TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
(TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
* target.h (struct target_def): Add pointer_mode, address_mode,
and valid_pointer_mode to addr_space substructure.
* target-def.h (TARGET_ADDR_SPACE_POINTER_MODE): Define.
(TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
(TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
(TARGET_ADDR_SPACE_HOOKS): Add them.
* targhooks.c (target_default_pointer_address_modes_p): New function.
* target.h (target_default_pointer_address_modes_p): Add prototype.
* targhooks.c (default_addr_space_pointer_mode): New function.
(default_addr_space_address_mode): Likewise.
(default_addr_space_valid_pointer_mode): Likewise.
* targhooks.h (default_addr_space_pointer_mode): Add prototype.
(default_addr_space_address_mode): Likewise.
(default_addr_space_valid_pointer_mode): Likewise.
* output.h (default_valid_pointer_mode): Move to ...
* targhooks.h (default_valid_pointer_mode): ... here.
* varasm.c (default_valid_pointer_mode): Move to ...
* targhooks.c (default_valid_pointer_mode): ... here.
* varasm.c (output_constant): Use targetm.addr_space.valid_pointer_mode
instead of targetm.valid_pointer_mode.
* fold-const.c (fit_double_type): Use int_or_pointer_precision.
* tree.c (integer_pow2p): Likewise.
(tree_log2): Likewise.
(tree_floor_log2): Likewise.
(signed_or_unsigned_type_for): Support pointer type of different size.
(int_or_pointer_precision): New function.
* tree.h (int_or_pointer_precision): Add prototype.
* stor-layout.c (layout_type): Set TYPE_PRECISION for offset types.
* varasm.c (initializer_constant_valid_p): Use TYPE_PRECISION of
incoming pointer type instead of POINTER_SIZE.
* tree.c (build_pointer_type): Use appropriate pointer mode
instead of ptr_mode.
(build_reference_type): Likewise.
* expr.c (store_expr): Likewise.
(expand_expr_addr_expr): Likewise.
* tree-vect-data-refs.c (vect_create_data_ref_ptr): Likewise.
* cfgexpand.c (expand_debug_expr): Likewise.
* auto-inc-dec.c: Include "target.h".
(try_merge): Use appropriate address mode instead of Pmode.
(find_inc): Likewise.
* combine.c (find_split_point): Likewise.
* cselib.c (cselib_record_sets): Likewise.
* dse.c (replace_inc_dec): Likewise.
(canon_address): Likewise.
* var-tracking.c (replace_expr_with_values): Likewise.
(count_uses): Likewise.
(add_uses): Likewise.
(add_stores): Likewise.
* emit-rtl.c: Include "target.h".
(adjust_address_1): Use appropriate address mode instead of Pmode.
(offset_address): Likewise.
* explow.c (break_out_memory_refs): Likewise.
(memory_address_addr_space): Likewise.
(promote_mode): Likewise.
* expr.c (move_by_pieces): Likewise.
(emit_block_move_via_loop): Likewise.
(store_by_pieces): Likewise.
(store_by_pieces_1): Likewise.
(expand_assignment): Likewise.
(store_constructor): Likewise.
(expand_expr_addr_expr): Likewise.
(expand_expr_real_1): Likewise.
* cfgexpand.c (expand_debug_expr): Likewise.
* ifcvt.c (noce_try_cmove_arith): Likewise.
* regcprop.c (kill_autoinc_value): Likewise.
* regmove.c (try_auto_increment): Likewise.
* reload.c (find_reloads): Likewise.
(find_reloads_address): Likewise.
(find_reloads_address_1): Likewise.
* sched-deps.c: Include "target.h".
(sched_analyze_1): Use appropriate address mode instead of Pmode.
(sched_analyze_2): Likewise.
* sel-sched-dump.c: Include "target.h".
(debug_mem_addr_value): Use appropriate address mode instead of Pmode.
* stor-layout.c (layout_type): Likewise.
* tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Likewise.
(multiplier_allowed_in_address_p): Likewise.
(get_address_cost): Likewise.
* varasm.c (make_decl_rtl): Likewise.
* expr.c (expand_assignment): Always convert offsets to appropriate
address mode.
(store_expr): Likewise.
(store_constructor): Likewise.
(expand_expr_real_1): Likewise.
* reload.h (form_sum): Add MODE argument.
* reload.c (form_sum): Add MODE argument, use it instead of Pmode.
Update recursive calls.
(subst_indexed_address): Update calls to form_sum.
* tree-flow.h (addr_for_mem_ref): Add ADDRSPACE argument.
* tree-ssa-address.c: Include "target.h".
(templates): Replace by ...
(mem_addr_template_list): ... this new vector.
(TEMPL_IDX): Handle address space numbers.
(gen_addr_rtx): Add address mode argument, use it instead of Pmode.
(addr_for_mem_ref): Add ADDRSPACE argument. Use per-address-space
instead of global cache. Update call to gen_addr_rtx.
(valid_mem_ref_p): Update call to addr_for_mem_ref.
* expr.c (expand_expr_real_1): Update call to addr_for_mem_ref.
* rtl.h (convert_memory_address_addr_space): Add prototype.
(convert_memory_address): Define as macro.
* explow.c (convert_memory_address): Rename to ...
(convert_memory_address_addr_space): ... this. Add ADDRSPACE argument.
Use appropriate pointer and address modes instead of ptr_mode / Pmode.
Update recursive calls.
(memory_address_addr_space): Call convert_memory_address_addr_space.
* expmed.c (make_tree): Likewise.
* expr.c (expand_assignment): Likewise.
(expand_expr_addr_expr_1): Likewise. Also, add ADDRSPACE argument.
(expand_expr_addr_expr): Likewise. Also, update call.
* alias.c (find_base_value): Guard pointer size optimizations.
(find_base_term): Likewise.
* rtlanal.c (nonzero_bits1): Likewise.
(num_sign_bit_copies1): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
* Makefile.in (tree-ssa-address.o): Add $(TARGET_H) dependency.
(emit-rtl.o): Likewise.
(auto-inc-dec.o): Likewise.
(sched-deps.o): Likewise.
2009-10-26 Ben Elliston <bje@au.ibm.com>
Michael Meissner <meissner@linux.vnet.ibm.com>
Ulrich Weigand <uweigand@de.ibm.com>

View File

@ -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) \

View File

@ -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));

View File

@ -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");

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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}

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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));
}

View File

@ -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);

View File

@ -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

View File

@ -52,9 +52,9 @@ unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNI
/* ... and its original value in bytes, specified via -fpack-struct=<value>. */
unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT;
/* Nonzero if all REFERENCE_TYPEs are internal and hence should be
allocated in Pmode, not ptr_mode. Set only by internal_reference_types
called only by a front end. */
/* Nonzero if all REFERENCE_TYPEs are internal and hence should be allocated
in the address spaces' address_mode, not pointer_mode. Set only by
internal_reference_types called only by a front end. */
static int reference_types_internal = 0;
static tree self_referential_size (tree);
@ -71,8 +71,8 @@ extern void debug_rli (record_layout_info);
static GTY(()) tree pending_sizes;
/* Show that REFERENCE_TYPES are internal and should be Pmode. Called only
by front end. */
/* Show that REFERENCE_TYPES are internal and should use address_mode.
Called only by front end. */
void
internal_reference_types (void)
@ -1917,6 +1917,7 @@ layout_type (tree type)
/* A pointer might be MODE_PARTIAL_INT,
but ptrdiff_t must be integral. */
SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
TYPE_PRECISION (type) = POINTER_SIZE;
break;
case FUNCTION_TYPE:
@ -1932,16 +1933,17 @@ layout_type (tree type)
case POINTER_TYPE:
case REFERENCE_TYPE:
{
enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
&& reference_types_internal)
? Pmode : TYPE_MODE (type));
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);
}
int nbits = GET_MODE_BITSIZE (mode);
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;

View File

@ -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, \

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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;
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);
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);
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;

View File

@ -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;

View File

@ -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));

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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. */