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:
parent
09e881c9e2
commit
d4ebfa65c9
137
gcc/ChangeLog
137
gcc/ChangeLog
|
@ -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>
|
||||
|
|
|
@ -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) \
|
||||
|
|
22
gcc/alias.c
22
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));
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
20
gcc/dse.c
20
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)
|
||||
|
|
|
@ -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);
|
||||
|
|
41
gcc/explow.c
41
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
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
144
gcc/expr.c
144
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
42
gcc/reload.c
42
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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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, \
|
||||
|
|
16
gcc/target.h
16
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
70
gcc/tree.c
70
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
32
gcc/varasm.c
32
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. */
|
||||
|
|
Loading…
Reference in New Issue