OSDN Git Service

2009-10-26 Ben Elliston <bje@au.ibm.com>
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Oct 2009 21:57:10 +0000 (21:57 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Oct 2009 21:57:10 +0000 (21:57 +0000)
    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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153573 138bc75d-0d04-0410-961f-82ee72b054a4

39 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/alias.c
gcc/auto-inc-dec.c
gcc/cfgexpand.c
gcc/combine.c
gcc/cselib.c
gcc/doc/tm.texi
gcc/dse.c
gcc/emit-rtl.c
gcc/explow.c
gcc/expmed.c
gcc/expr.c
gcc/fold-const.c
gcc/ifcvt.c
gcc/output.h
gcc/regcprop.c
gcc/regmove.c
gcc/reload.c
gcc/reload.h
gcc/reload1.c
gcc/rtl.h
gcc/rtlanal.c
gcc/sched-deps.c
gcc/sel-sched-dump.c
gcc/simplify-rtx.c
gcc/stor-layout.c
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h
gcc/tree-flow.h
gcc/tree-ssa-address.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-vect-data-refs.c
gcc/tree.c
gcc/tree.h
gcc/var-tracking.c
gcc/varasm.c

index ebe6aec..658274d 100644 (file)
@@ -2,6 +2,143 @@
            Michael Meissner  <meissner@linux.vnet.ibm.com>
            Ulrich Weigand  <uweigand@de.ibm.com>
 
+       * doc/tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.
+       (TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
+       (TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
+
+       * target.h (struct target_def): Add pointer_mode, address_mode,
+       and valid_pointer_mode to addr_space substructure.
+       * target-def.h (TARGET_ADDR_SPACE_POINTER_MODE): Define.
+       (TARGET_ADDR_SPACE_ADDRESS_MODE): Likewise.
+       (TARGET_ADDR_SPACE_VALID_POINTER_MODE): Likewise.
+       (TARGET_ADDR_SPACE_HOOKS): Add them.
+       * targhooks.c (target_default_pointer_address_modes_p): New function.
+       * target.h (target_default_pointer_address_modes_p): Add prototype.
+       * targhooks.c (default_addr_space_pointer_mode): New function.
+       (default_addr_space_address_mode): Likewise.
+       (default_addr_space_valid_pointer_mode): Likewise.
+       * targhooks.h (default_addr_space_pointer_mode): Add prototype.
+       (default_addr_space_address_mode): Likewise.
+       (default_addr_space_valid_pointer_mode): Likewise.
+       * output.h (default_valid_pointer_mode): Move to ...
+       * targhooks.h (default_valid_pointer_mode): ... here.
+       * varasm.c (default_valid_pointer_mode): Move to ...
+       * targhooks.c (default_valid_pointer_mode): ... here.
+
+       * varasm.c (output_constant): Use targetm.addr_space.valid_pointer_mode
+       instead of targetm.valid_pointer_mode.
+
+       * fold-const.c (fit_double_type): Use int_or_pointer_precision.
+       * tree.c (integer_pow2p): Likewise.
+       (tree_log2): Likewise.
+       (tree_floor_log2): Likewise.
+       (signed_or_unsigned_type_for): Support pointer type of different size.
+       (int_or_pointer_precision): New function.
+       * tree.h (int_or_pointer_precision): Add prototype.
+       * stor-layout.c (layout_type): Set TYPE_PRECISION for offset types.
+       * varasm.c (initializer_constant_valid_p): Use TYPE_PRECISION of
+       incoming pointer type instead of POINTER_SIZE.
+
+       * tree.c (build_pointer_type): Use appropriate pointer mode
+       instead of ptr_mode.
+       (build_reference_type): Likewise.
+       * expr.c (store_expr): Likewise.
+       (expand_expr_addr_expr): Likewise.
+       * tree-vect-data-refs.c (vect_create_data_ref_ptr): Likewise.
+       * cfgexpand.c (expand_debug_expr): Likewise.
+       
+       * auto-inc-dec.c: Include "target.h".
+       (try_merge): Use appropriate address mode instead of Pmode.
+       (find_inc): Likewise.
+       * combine.c (find_split_point): Likewise.
+       * cselib.c (cselib_record_sets): Likewise.
+       * dse.c (replace_inc_dec): Likewise.
+       (canon_address): Likewise.
+       * var-tracking.c (replace_expr_with_values): Likewise.
+       (count_uses): Likewise.
+       (add_uses): Likewise.
+       (add_stores): Likewise.
+       * emit-rtl.c: Include "target.h".
+       (adjust_address_1): Use appropriate address mode instead of Pmode.
+       (offset_address): Likewise.
+       * explow.c (break_out_memory_refs): Likewise.
+       (memory_address_addr_space): Likewise.
+       (promote_mode): Likewise.
+       * expr.c (move_by_pieces): Likewise.
+       (emit_block_move_via_loop): Likewise.
+       (store_by_pieces): Likewise.
+       (store_by_pieces_1): Likewise.
+       (expand_assignment): Likewise.
+       (store_constructor): Likewise.
+       (expand_expr_addr_expr): Likewise.
+       (expand_expr_real_1): Likewise.
+       * cfgexpand.c (expand_debug_expr): Likewise.
+       * ifcvt.c (noce_try_cmove_arith): Likewise.
+       * regcprop.c (kill_autoinc_value): Likewise.
+       * regmove.c (try_auto_increment): Likewise.
+       * reload.c (find_reloads): Likewise.
+       (find_reloads_address): Likewise.
+       (find_reloads_address_1): Likewise.
+       * sched-deps.c: Include "target.h".
+       (sched_analyze_1): Use appropriate address mode instead of Pmode.
+       (sched_analyze_2): Likewise.
+       * sel-sched-dump.c: Include "target.h".
+       (debug_mem_addr_value): Use appropriate address mode instead of Pmode.
+       * stor-layout.c (layout_type): Likewise.
+       * tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Likewise.
+       (multiplier_allowed_in_address_p): Likewise.
+       (get_address_cost): Likewise.
+       * varasm.c (make_decl_rtl): Likewise.
+       
+       * expr.c (expand_assignment): Always convert offsets to appropriate
+       address mode.
+       (store_expr): Likewise.
+       (store_constructor): Likewise.
+       (expand_expr_real_1): Likewise.
+
+       * reload.h (form_sum): Add MODE argument.
+       * reload.c (form_sum): Add MODE argument, use it instead of Pmode.
+       Update recursive calls.
+       (subst_indexed_address): Update calls to form_sum.
+       
+       * tree-flow.h (addr_for_mem_ref): Add ADDRSPACE argument.
+       * tree-ssa-address.c: Include "target.h".
+       (templates): Replace by ...
+       (mem_addr_template_list): ... this new vector.
+       (TEMPL_IDX): Handle address space numbers.
+       (gen_addr_rtx): Add address mode argument, use it instead of Pmode.
+       (addr_for_mem_ref): Add ADDRSPACE argument.  Use per-address-space
+       instead of global cache.  Update call to gen_addr_rtx.
+       (valid_mem_ref_p): Update call to addr_for_mem_ref.
+       * expr.c (expand_expr_real_1): Update call to addr_for_mem_ref.
+       
+       * rtl.h (convert_memory_address_addr_space): Add prototype.
+       (convert_memory_address): Define as macro.
+       * explow.c (convert_memory_address): Rename to ...
+       (convert_memory_address_addr_space): ... this.  Add ADDRSPACE argument.
+       Use appropriate pointer and address modes instead of ptr_mode / Pmode.
+       Update recursive calls.
+       (memory_address_addr_space): Call convert_memory_address_addr_space.
+       * expmed.c (make_tree): Likewise.
+       * expr.c (expand_assignment): Likewise.
+       (expand_expr_addr_expr_1): Likewise.  Also, add ADDRSPACE argument.
+       (expand_expr_addr_expr): Likewise.  Also, update call.
+
+       * alias.c (find_base_value): Guard pointer size optimizations.
+       (find_base_term): Likewise.
+       * rtlanal.c (nonzero_bits1): Likewise.
+       (num_sign_bit_copies1): Likewise.
+       * simplify-rtx.c (simplify_unary_operation_1): Likewise.
+
+       * Makefile.in (tree-ssa-address.o): Add $(TARGET_H) dependency.
+       (emit-rtl.o): Likewise.
+       (auto-inc-dec.o): Likewise.
+       (sched-deps.o): Likewise.
+
+2009-10-26  Ben Elliston  <bje@au.ibm.com>
+           Michael Meissner  <meissner@linux.vnet.ibm.com>
+           Ulrich Weigand  <uweigand@de.ibm.com>
+
        * doc/extend.texi (Named Address Spaces): New section.
        * coretypes.h (addr_space_t): New type.
        (ADDR_SPACE_GENERIC): New define.
index 934c4ed..5dd47e5 100644 (file)
@@ -2432,7 +2432,7 @@ tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \
    output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
    $(TREE_PASS_H) $(FLAGS_H) $(TREE_INLINE_H) $(RECOG_H) insn-config.h \
-   $(EXPR_H) gt-tree-ssa-address.h $(GGC_H) tree-affine.h
+   $(EXPR_H) gt-tree-ssa-address.h $(GGC_H) tree-affine.h $(TARGET_H)
 tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \
    $(TREE_INLINE_H) output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -2824,7 +2824,7 @@ emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
    $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
    $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
-   $(REAL_H) $(DF_H) $(PARAMS_H)
+   $(REAL_H) $(DF_H) $(PARAMS_H) $(TARGET_H)
 real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
 dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)        $(TREE_H) \
@@ -3034,7 +3034,7 @@ alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
 auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \
    $(REGS_H) $(FLAGS_H) output.h $(FUNCTION_H) $(EXCEPT_H) $(TOPLEV_H) $(RECOG_H) \
-   $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H)
+   $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H)
 cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
    $(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) $(FUNCTION_H) $(EXCEPT_H) $(GGC_H) \
    $(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h \
@@ -3215,7 +3215,7 @@ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_
 sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
    $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
-   ira.h $(PARAMS_H) $(TM_P_H) ira.h
+   ira.h $(PARAMS_H) $(TM_P_H) ira.h $(TARGET_H)
 sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
    $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
index b6d0b7e..40226f2 100644 (file)
@@ -1060,6 +1060,11 @@ find_base_value (rtx src)
       return 0;
 
     case TRUNCATE:
+      /* As we do not know which address space the pointer is refering to, we can
+        handle this only if the target does not support different pointer or
+        address modes depending on the address space.  */
+      if (!target_default_pointer_address_modes_p ())
+       break;
       if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
        break;
       /* Fall through.  */
@@ -1074,6 +1079,12 @@ find_base_value (rtx src)
 
     case ZERO_EXTEND:
     case SIGN_EXTEND:  /* used for NT/Alpha pointers */
+      /* As we do not know which address space the pointer is refering to, we can
+        handle this only if the target does not support different pointer or
+        address modes depending on the address space.  */
+      if (!target_default_pointer_address_modes_p ())
+       break;
+
       {
        rtx temp = find_base_value (XEXP (src, 0));
 
@@ -1466,6 +1477,11 @@ find_base_term (rtx x)
       return REG_BASE_VALUE (x);
 
     case TRUNCATE:
+      /* As we do not know which address space the pointer is refering to, we can
+        handle this only if the target does not support different pointer or
+        address modes depending on the address space.  */
+      if (!target_default_pointer_address_modes_p ())
+       return 0;
       if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
        return 0;
       /* Fall through.  */
@@ -1480,6 +1496,12 @@ find_base_term (rtx x)
 
     case ZERO_EXTEND:
     case SIGN_EXTEND:  /* Used for Alpha/NT pointers */
+      /* As we do not know which address space the pointer is refering to, we can
+        handle this only if the target does not support different pointer or
+        address modes depending on the address space.  */
+      if (!target_default_pointer_address_modes_p ())
+       return 0;
+
       {
        rtx temp = find_base_term (XEXP (x, 0));
 
index 929a2dc..3b3006c 100644 (file)
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "df.h"
 #include "dbgcnt.h"
+#include "target.h"
 
 /* This pass was originally removed from flow.c. However there is
    almost nothing that remains of that code.
@@ -613,6 +614,7 @@ try_merge (void)
   /* The width of the mem being accessed.  */
   int size = GET_MODE_SIZE (GET_MODE (mem));
   rtx last_insn = NULL;
+  enum machine_mode reg_mode = GET_MODE (inc_reg);
 
   switch (inc_insn.form)
     {
@@ -667,33 +669,33 @@ try_merge (void)
     case SIMPLE_PRE_INC:     /* ++size  */
       if (dump_file)
        fprintf (dump_file, "trying SIMPLE_PRE_INC\n");
-      return attempt_change (gen_rtx_PRE_INC (Pmode, inc_reg), inc_reg);
+      return attempt_change (gen_rtx_PRE_INC (reg_mode, inc_reg), inc_reg);
       break;
       
     case SIMPLE_POST_INC:    /* size++  */
       if (dump_file)
        fprintf (dump_file, "trying SIMPLE_POST_INC\n");
-      return attempt_change (gen_rtx_POST_INC (Pmode, inc_reg), inc_reg);
+      return attempt_change (gen_rtx_POST_INC (reg_mode, inc_reg), inc_reg);
       break;
       
     case SIMPLE_PRE_DEC:     /* --size  */
       if (dump_file)
        fprintf (dump_file, "trying SIMPLE_PRE_DEC\n");
-      return attempt_change (gen_rtx_PRE_DEC (Pmode, inc_reg), inc_reg);
+      return attempt_change (gen_rtx_PRE_DEC (reg_mode, inc_reg), inc_reg);
       break;
       
     case SIMPLE_POST_DEC:    /* size--  */
       if (dump_file)
        fprintf (dump_file, "trying SIMPLE_POST_DEC\n");
-      return attempt_change (gen_rtx_POST_DEC (Pmode, inc_reg), inc_reg);
+      return attempt_change (gen_rtx_POST_DEC (reg_mode, inc_reg), inc_reg);
       break;
       
     case DISP_PRE:           /* ++con   */
       if (dump_file)
        fprintf (dump_file, "trying DISP_PRE\n");
-      return attempt_change (gen_rtx_PRE_MODIFY (Pmode, 
+      return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
                                                 inc_reg,
-                                                gen_rtx_PLUS (Pmode,
+                                                gen_rtx_PLUS (reg_mode,
                                                               inc_reg,
                                                               inc_insn.reg1)),
                             inc_reg);
@@ -702,9 +704,9 @@ try_merge (void)
     case DISP_POST:          /* con++   */
       if (dump_file)
        fprintf (dump_file, "trying POST_DISP\n");
-      return attempt_change (gen_rtx_POST_MODIFY (Pmode,
+      return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
                                                  inc_reg,
-                                                 gen_rtx_PLUS (Pmode,
+                                                 gen_rtx_PLUS (reg_mode,
                                                                inc_reg,
                                                                inc_insn.reg1)),
                             inc_reg);
@@ -713,9 +715,9 @@ try_merge (void)
     case REG_PRE:            /* ++reg   */
       if (dump_file)
        fprintf (dump_file, "trying PRE_REG\n");
-      return attempt_change (gen_rtx_PRE_MODIFY (Pmode, 
+      return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
                                                 inc_reg,
-                                                gen_rtx_PLUS (Pmode,
+                                                gen_rtx_PLUS (reg_mode,
                                                               inc_reg,
                                                               inc_insn.reg1)),
                             inc_reg);
@@ -724,9 +726,9 @@ try_merge (void)
     case REG_POST:            /* reg++   */
       if (dump_file)
        fprintf (dump_file, "trying POST_REG\n");
-      return attempt_change (gen_rtx_POST_MODIFY (Pmode, 
+      return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
                                                  inc_reg,
-                                                 gen_rtx_PLUS (Pmode,
+                                                 gen_rtx_PLUS (reg_mode,
                                                                inc_reg,
                                                                inc_insn.reg1)),
                             inc_reg);
@@ -1089,7 +1091,9 @@ find_inc (bool first_try)
                     we are going to increment the result of the add insn.
                     For this trick to be correct, the result reg of
                     the inc must be a valid addressing reg.  */
-                 if (GET_MODE (inc_insn.reg_res) != Pmode)
+                 addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
+                 if (GET_MODE (inc_insn.reg_res)
+                     != targetm.addr_space.address_mode (as))
                    {
                      if (dump_file)
                        fprintf (dump_file, "base reg mode failure.\n");
@@ -1138,7 +1142,9 @@ find_inc (bool first_try)
        {
          /* For this trick to be correct, the result reg of the inc
             must be a valid addressing reg.  */
-         if (GET_MODE (inc_insn.reg_res) != Pmode)
+         addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
+         if (GET_MODE (inc_insn.reg_res)
+             != targetm.addr_space.address_mode (as))
            {
              if (dump_file)
                fprintf (dump_file, "base reg mode failure.\n");
index 21b900a..fdc4de5 100644 (file)
@@ -2236,6 +2236,8 @@ expand_debug_expr (tree exp)
   enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
   addr_space_t as;
+  enum machine_mode address_mode;
+  enum machine_mode pointer_mode;
 
   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
     {
@@ -2434,15 +2436,18 @@ expand_debug_expr (tree exp)
       else
        as = ADDR_SPACE_GENERIC;
 
-      gcc_assert (GET_MODE (op0) == Pmode
-                 || GET_MODE (op0) == ptr_mode
+      address_mode = targetm.addr_space.address_mode (as);
+      pointer_mode = targetm.addr_space.pointer_mode (as);
+
+      gcc_assert (GET_MODE (op0) == address_mode
+                 || GET_MODE (op0) == pointer_mode
                  || GET_CODE (op0) == CONST_INT
                  || GET_CODE (op0) == CONST_DOUBLE);
 
       if (TREE_CODE (exp) == ALIGN_INDIRECT_REF)
        {
          int align = TYPE_ALIGN_UNIT (TREE_TYPE (exp));
-         op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
+         op0 = gen_rtx_AND (address_mode, op0, GEN_INT (-align));
        }
 
       op0 = gen_rtx_MEM (mode, op0);
@@ -2463,9 +2468,11 @@ expand_debug_expr (tree exp)
        return NULL;
 
       as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
+      address_mode = targetm.addr_space.address_mode (as);
+      pointer_mode = targetm.addr_space.pointer_mode (as);
 
-      gcc_assert (GET_MODE (op0) == Pmode
-                 || GET_MODE (op0) == ptr_mode
+      gcc_assert (GET_MODE (op0) == address_mode
+                 || GET_MODE (op0) == pointer_mode
                  || GET_CODE (op0) == CONST_INT
                  || GET_CODE (op0) == CONST_DOUBLE);
 
index 89dc415..2311755 100644 (file)
@@ -4159,9 +4159,12 @@ find_split_point (rtx *loc, rtx insn)
       if (GET_CODE (XEXP (x, 0)) == CONST
          || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
        {
+         enum machine_mode address_mode
+           = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+
          SUBST (XEXP (x, 0),
-                gen_rtx_LO_SUM (Pmode,
-                                gen_rtx_HIGH (Pmode, XEXP (x, 0)),
+                gen_rtx_LO_SUM (address_mode,
+                                gen_rtx_HIGH (address_mode, XEXP (x, 0)),
                                 XEXP (x, 0)));
          return &XEXP (XEXP (x, 0), 0);
        }
index 7065429..0aa22a4 100644 (file)
@@ -1890,7 +1890,13 @@ cselib_record_sets (rtx insn)
            src = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, src, dest);
          sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1);
          if (MEM_P (dest))
-           sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), Pmode, 1);
+           {
+             enum machine_mode address_mode
+               = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
+
+             sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0),
+                                                    address_mode, 1);
+           }
          else
            sets[i].dest_addr_elt = 0;
        }
index 4a2fe56..26b5a14 100644 (file)
@@ -9855,6 +9855,30 @@ Internally, address spaces are represented as a small integer in the
 range 0 to 15 with address space 0 being reserved for the generic
 address space.
 
+@deftypefn {Target Hook} {enum machine_mode} TARGET_ADDR_SPACE_POINTER_MODE (addr_space_t @var{address_space})
+Define this to return the machine mode to use for pointers to
+@var{address_space} if the target supports named address spaces.
+The default version of this hook returns @code{ptr_mode} for the
+generic address space only.
+@end deftypefn
+
+@deftypefn {Target Hook} {enum machine_mode} TARGET_ADDR_SPACE_ADDRESS_MODE (addr_space_t @var{address_space})
+Define this to return the machine mode to use for addresses in
+@var{address_space} if the target supports named address spaces.
+The default version of this hook returns @code{Pmode} for the
+generic address space only.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_ADDR_SPACE_VALID_POINTER_MODE (enum machine_mode @var{mode}, addr_space_t @var{as})
+Define this to return nonzero if the port can handle pointers
+with machine mode @var{mode} to address space @var{as}.  This target
+hook is the same as the @code{TARGET_VALID_POINTER_MODE} target hook,
+except that it includes explicit named address space support.  The default
+version of this hook returns true for the modes returned by either the
+@code{TARGET_ADDR_SPACE_POINTER_MODE} or @code{TARGET_ADDR_SPACE_ADDRESS_MODE}
+target hooks for the given address space.
+@end deftypefn
+
 @deftypefn {Target Hook} {bool} TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P (enum machine_mode @var{mode}, rtx @var{exp}, bool @var{strict}, addr_space_t @var{as})
 Define this to return true if @var{exp} is a valid address for mode
 @var{mode} in the named address space @var{as}.  The @var{strict}
index f11c34a..a883bcd 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -826,9 +826,9 @@ replace_inc_dec (rtx *r, void *d)
     case POST_INC:
       {
        rtx r1 = XEXP (x, 0);
-       rtx c = gen_int_mode (data->size, Pmode);
-       emit_insn_before (gen_rtx_SET (Pmode, r1, 
-                                      gen_rtx_PLUS (Pmode, r1, c)),
+       rtx c = gen_int_mode (data->size, GET_MODE (r1));
+       emit_insn_before (gen_rtx_SET (VOIDmode, r1,
+                                      gen_rtx_PLUS (GET_MODE (r1), r1, c)),
                          data->insn);
        return -1;
       }
@@ -837,9 +837,9 @@ replace_inc_dec (rtx *r, void *d)
     case POST_DEC:
       {
        rtx r1 = XEXP (x, 0);
-       rtx c = gen_int_mode (-data->size, Pmode);
-       emit_insn_before (gen_rtx_SET (Pmode, r1, 
-                                      gen_rtx_PLUS (Pmode, r1, c)),
+       rtx c = gen_int_mode (-data->size, GET_MODE (r1));
+       emit_insn_before (gen_rtx_SET (VOIDmode, r1,
+                                      gen_rtx_PLUS (GET_MODE (r1), r1, c)),
                          data->insn);
        return -1;
       }
@@ -851,7 +851,7 @@ replace_inc_dec (rtx *r, void *d)
           insn that contained it.  */
        rtx add = XEXP (x, 0);
        rtx r1 = XEXP (add, 0);
-       emit_insn_before (gen_rtx_SET (Pmode, r1, add), data->insn);
+       emit_insn_before (gen_rtx_SET (VOIDmode, r1, add), data->insn);
        return -1;
       }
 
@@ -1068,6 +1068,8 @@ canon_address (rtx mem,
               HOST_WIDE_INT *offset, 
               cselib_val **base)
 {
+  enum machine_mode address_mode
+    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
   rtx mem_address = XEXP (mem, 0);
   rtx expanded_address, address;
   int expanded;
@@ -1107,7 +1109,7 @@ canon_address (rtx mem,
 
   *alias_set_out = 0;
 
-  cselib_lookup (mem_address, Pmode, 1);
+  cselib_lookup (mem_address, address_mode, 1);
 
   if (dump_file)
     {
@@ -1187,7 +1189,7 @@ canon_address (rtx mem,
        }
     }
 
-  *base = cselib_lookup (address, Pmode, true);
+  *base = cselib_lookup (address, address_mode, true);
   *group_id = -1;
 
   if (*base == NULL)
index baad4a8..d7600bc 100644 (file)
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "df.h"
 #include "params.h"
+#include "target.h"
 
 /* Commonly used modes.  */
 
@@ -1975,6 +1976,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
   rtx size = 0;
   unsigned int memalign = MEM_ALIGN (memref);
   addr_space_t as = MEM_ADDR_SPACE (memref);
+  enum machine_mode address_mode = targetm.addr_space.address_mode (as);
   int pbits;
 
   /* If there are no changes, just return the original memory reference.  */
@@ -1989,7 +1991,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
 
   /* Convert a possibly large offset to a signed value within the
      range of the target address space.  */
-  pbits = GET_MODE_BITSIZE (Pmode);
+  pbits = GET_MODE_BITSIZE (address_mode);
   if (HOST_BITS_PER_WIDE_INT > pbits)
     {
       int shift = HOST_BITS_PER_WIDE_INT - pbits;
@@ -2005,7 +2007,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
          && offset >= 0
          && (unsigned HOST_WIDE_INT) offset
              < GET_MODE_ALIGNMENT (GET_MODE (memref)) / BITS_PER_UNIT)
-       addr = gen_rtx_LO_SUM (Pmode, XEXP (addr, 0),
+       addr = gen_rtx_LO_SUM (address_mode, XEXP (addr, 0),
                               plus_constant (XEXP (addr, 1), offset));
       else
        addr = plus_constant (addr, offset);
@@ -2068,8 +2070,9 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
 {
   rtx new_rtx, addr = XEXP (memref, 0);
   addr_space_t as = MEM_ADDR_SPACE (memref);
+  enum machine_mode address_mode = targetm.addr_space.address_mode (as);
 
-  new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
+  new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
 
   /* At this point we don't know _why_ the address is invalid.  It
      could have secondary memory references, multiplies or anything.
@@ -2083,7 +2086,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
       && XEXP (addr, 0) == pic_offset_table_rtx)
     {
       addr = force_reg (GET_MODE (addr), addr);
-      new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
+      new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
     }
 
   update_temp_slot_address (XEXP (memref, 0), new_rtx);
index 1115f22..c38682d 100644 (file)
@@ -306,27 +306,27 @@ break_out_memory_refs (rtx x)
       rtx op1 = break_out_memory_refs (XEXP (x, 1));
 
       if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
-       x = simplify_gen_binary (GET_CODE (x), Pmode, op0, op1);
+       x = simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, op1);
     }
 
   return x;
 }
 
-/* Given X, a memory address in ptr_mode, convert it to an address
-   in Pmode, or vice versa (TO_MODE says which way).  We take advantage of
-   the fact that pointers are not allowed to overflow by commuting arithmetic
-   operations over conversions so that address arithmetic insns can be
-   used.  */
+/* Given X, a memory address in address space AS' pointer mode, convert it to
+   an address in the address space's address mode, or vice versa (TO_MODE says
+   which way).  We take advantage of the fact that pointers are not allowed to
+   overflow by commuting arithmetic operations over conversions so that address
+   arithmetic insns can be used.  */
 
 rtx
-convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED, 
-                       rtx x)
+convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
+                                  rtx x, addr_space_t as ATTRIBUTE_UNUSED)
 {
 #ifndef POINTERS_EXTEND_UNSIGNED
   gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode);
   return x;
 #else /* defined(POINTERS_EXTEND_UNSIGNED) */
-  enum machine_mode from_mode;
+  enum machine_mode pointer_mode, address_mode, from_mode;
   rtx temp;
   enum rtx_code code;
 
@@ -334,7 +334,9 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
   if (GET_MODE (x) == to_mode)
     return x;
 
-  from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
+  pointer_mode = targetm.addr_space.pointer_mode (as);
+  address_mode = targetm.addr_space.address_mode (as);
+  from_mode = to_mode == pointer_mode ? address_mode : pointer_mode;
 
   /* Here we handle some special cases.  If none of them apply, fall through
      to the default case.  */
@@ -375,7 +377,8 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
 
     case CONST:
       return gen_rtx_CONST (to_mode,
-                           convert_memory_address (to_mode, XEXP (x, 0)));
+                           convert_memory_address_addr_space
+                             (to_mode, XEXP (x, 0), as));
       break;
 
     case PLUS:
@@ -389,10 +392,12 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
          || (GET_CODE (x) == PLUS
              && CONST_INT_P (XEXP (x, 1))
-             && (XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1))
+             && (XEXP (x, 1) == convert_memory_address_addr_space
+                                  (to_mode, XEXP (x, 1), as)
                  || POINTERS_EXTEND_UNSIGNED < 0)))
        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
-                              convert_memory_address (to_mode, XEXP (x, 0)),
+                              convert_memory_address_addr_space
+                                (to_mode, XEXP (x, 0), as),
                               XEXP (x, 1));
       break;
 
@@ -413,13 +418,14 @@ rtx
 memory_address_addr_space (enum machine_mode mode, rtx x, addr_space_t as)
 {
   rtx oldx = x;
+  enum machine_mode address_mode = targetm.addr_space.address_mode (as);
 
-  x = convert_memory_address (Pmode, x);
+  x = convert_memory_address_addr_space (address_mode, x, as);
 
   /* By passing constant addresses through registers
      we get a chance to cse them.  */
   if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
-    x = force_reg (Pmode, x);
+    x = force_reg (address_mode, x);
 
   /* We get better cse by rejecting indirect addressing at this stage.
      Let the combiner create indirect addresses where appropriate.
@@ -490,7 +496,7 @@ memory_address_addr_space (enum machine_mode mode, rtx x, addr_space_t as)
       /* Last resort: copy the value to a register, since
         the register is a valid address.  */
       else
-       x = force_reg (Pmode, x);
+       x = force_reg (address_mode, x);
     }
 
  done:
@@ -801,7 +807,8 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, enum machine_mode mode,
     case REFERENCE_TYPE:
     case POINTER_TYPE:
       *punsignedp = POINTERS_EXTEND_UNSIGNED;
-      return Pmode;
+      return targetm.addr_space.address_mode
+              (TYPE_ADDR_SPACE (TREE_TYPE (type)));
       break;
 #endif
 
index 98a99a2..12370d0 100644 (file)
@@ -5089,10 +5089,11 @@ make_tree (tree type, rtx x)
     default:
       t = build_decl (RTL_LOCATION (x), VAR_DECL, NULL_TREE, type);
 
-      /* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
-        ptr_mode.  So convert.  */
+      /* If TYPE is a POINTER_TYPE, we might need to convert X from
+        address mode to pointer mode.  */
       if (POINTER_TYPE_P (type))
-       x = convert_memory_address (TYPE_MODE (type), x);
+       x = convert_memory_address_addr_space
+             (TYPE_MODE (type), x, TYPE_ADDR_SPACE (TREE_TYPE (type)));
 
       /* Note that we do *not* use SET_DECL_RTL here, because we do not
         want set_decl_rtl to go adjusting REG_ATTRS for this temporary.  */
index 5e8fae1..e62b530 100644 (file)
@@ -877,6 +877,8 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
                unsigned int align, int endp)
 {
   struct move_by_pieces_d data;
+  enum machine_mode to_addr_mode, from_addr_mode
+    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (from));
   rtx to_addr, from_addr = XEXP (from, 0);
   unsigned int max_size = MOVE_MAX_PIECES + 1;
   enum machine_mode mode = VOIDmode, tmode;
@@ -888,6 +890,7 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
   data.from_addr = from_addr;
   if (to)
     {
+      to_addr_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to));
       to_addr = XEXP (to, 0);
       data.to = to;
       data.autinc_to
@@ -898,6 +901,7 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
     }
   else
     {
+      to_addr_mode = VOIDmode;
       to_addr = NULL_RTX;
       data.to = NULL_RTX;
       data.autinc_to = 1;
@@ -933,32 +937,34 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
 
       if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
        {
-         data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
+         data.from_addr = copy_to_mode_reg (from_addr_mode,
+                                            plus_constant (from_addr, len));
          data.autinc_from = 1;
          data.explicit_inc_from = -1;
        }
       if (USE_LOAD_POST_INCREMENT (mode) && ! data.autinc_from)
        {
-         data.from_addr = copy_addr_to_reg (from_addr);
+         data.from_addr = copy_to_mode_reg (from_addr_mode, from_addr);
          data.autinc_from = 1;
          data.explicit_inc_from = 1;
        }
       if (!data.autinc_from && CONSTANT_P (from_addr))
-       data.from_addr = copy_addr_to_reg (from_addr);
+       data.from_addr = copy_to_mode_reg (from_addr_mode, from_addr);
       if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
        {
-         data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
+         data.to_addr = copy_to_mode_reg (to_addr_mode,
+                                          plus_constant (to_addr, len));
          data.autinc_to = 1;
          data.explicit_inc_to = -1;
        }
       if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
        {
-         data.to_addr = copy_addr_to_reg (to_addr);
+         data.to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
          data.autinc_to = 1;
          data.explicit_inc_to = 1;
        }
       if (!data.autinc_to && CONSTANT_P (to_addr))
-       data.to_addr = copy_addr_to_reg (to_addr);
+       data.to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
     }
 
   tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
@@ -1013,7 +1019,8 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
              if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
                emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
              else
-               data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
+               data.to_addr = copy_to_mode_reg (to_addr_mode,
+                                                plus_constant (data.to_addr,
                                                                -1));
            }
          to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
@@ -1468,6 +1475,10 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
                          unsigned int align ATTRIBUTE_UNUSED)
 {
   rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
+  enum machine_mode x_addr_mode
+    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+  enum machine_mode y_addr_mode
+    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (y));
   enum machine_mode iter_mode;
 
   iter_mode = GET_MODE (size);
@@ -1487,9 +1498,13 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
   emit_jump (cmp_label);
   emit_label (top_label);
 
-  tmp = convert_modes (Pmode, iter_mode, iter, true);
-  x_addr = gen_rtx_PLUS (Pmode, x_addr, tmp);
-  y_addr = gen_rtx_PLUS (Pmode, y_addr, tmp);
+  tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
+  x_addr = gen_rtx_PLUS (x_addr_mode, x_addr, tmp);
+
+  if (x_addr_mode != y_addr_mode)
+    tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
+  y_addr = gen_rtx_PLUS (y_addr_mode, y_addr, tmp);
+
   x = change_address (x, QImode, x_addr);
   y = change_address (y, QImode, y_addr);
 
@@ -2384,6 +2399,8 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
                 rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
                 void *constfundata, unsigned int align, bool memsetp, int endp)
 {
+  enum machine_mode to_addr_mode
+    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to));
   struct store_by_pieces_d data;
 
   if (len == 0)
@@ -2412,7 +2429,8 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
              if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
                emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
              else
-               data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
+               data.to_addr = copy_to_mode_reg (to_addr_mode,
+                                                plus_constant (data.to_addr,
                                                                -1));
            }
          to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
@@ -2467,6 +2485,8 @@ static void
 store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
                   unsigned int align ATTRIBUTE_UNUSED)
 {
+  enum machine_mode to_addr_mode
+    = targetm.addr_space.address_mode (MEM_ADDR_SPACE (data->to));
   rtx to_addr = XEXP (data->to, 0);
   unsigned int max_size = STORE_MAX_PIECES + 1;
   enum machine_mode mode = VOIDmode, tmode;
@@ -2498,7 +2518,8 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
 
       if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
        {
-         data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
+         data->to_addr = copy_to_mode_reg (to_addr_mode,
+                                           plus_constant (to_addr, data->len));
          data->autinc_to = 1;
          data->explicit_inc_to = -1;
        }
@@ -2506,13 +2527,13 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
       if (USE_STORE_POST_INCREMENT (mode) && ! data->reverse
          && ! data->autinc_to)
        {
-         data->to_addr = copy_addr_to_reg (to_addr);
+         data->to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
          data->autinc_to = 1;
          data->explicit_inc_to = 1;
        }
 
       if ( !data->autinc_to && CONSTANT_P (to_addr))
-       data->to_addr = copy_addr_to_reg (to_addr);
+       data->to_addr = copy_to_mode_reg (to_addr_mode, to_addr);
     }
 
   tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
@@ -4214,6 +4235,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
 
       if (offset != 0)
        {
+         enum machine_mode address_mode;
          rtx offset_rtx;
 
          if (!MEM_P (to_rtx))
@@ -4226,13 +4248,10 @@ expand_assignment (tree to, tree from, bool nontemporal)
            }
 
          offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
-#ifdef POINTERS_EXTEND_UNSIGNED
-         if (GET_MODE (offset_rtx) != Pmode)
-           offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-#else
-         if (GET_MODE (offset_rtx) != ptr_mode)
-           offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-#endif
+         address_mode
+           = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to_rtx));
+         if (GET_MODE (offset_rtx) != address_mode)
+           offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
 
          /* A constant address in TO_RTX can have VOIDmode, we must not try
             to call force_reg for that case.  Avoid that case.  */
@@ -4371,7 +4390,10 @@ expand_assignment (tree to, tree from, bool nontemporal)
       else
        {
          if (POINTER_TYPE_P (TREE_TYPE (to)))
-           value = convert_memory_address (GET_MODE (to_rtx), value);
+           value = convert_memory_address_addr_space
+                     (GET_MODE (to_rtx), value,
+                      TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
+
          emit_move_insn (to_rtx, value);
        }
       preserve_temp_slots (to_rtx);
@@ -4731,6 +4753,11 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
                              ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
          else
            {
+             enum machine_mode pointer_mode
+               = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
+             enum machine_mode address_mode
+               = targetm.addr_space.address_mode (MEM_ADDR_SPACE (target));
+
              /* Compute the size of the data to copy from the string.  */
              tree copy_size
                = size_binop_loc (loc, MIN_EXPR,
@@ -4743,14 +4770,14 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
              rtx label = 0;
 
              /* Copy that much.  */
-             copy_size_rtx = convert_to_mode (ptr_mode, copy_size_rtx,
+             copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
                                               TYPE_UNSIGNED (sizetype));
              emit_block_move (target, temp, copy_size_rtx,
                               (call_param_p
                                ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
 
              /* Figure out how much is left in TARGET that we have to clear.
-                Do all calculations in ptr_mode.  */
+                Do all calculations in pointer_mode.  */
              if (CONST_INT_P (copy_size_rtx))
                {
                  size = plus_constant (size, -INTVAL (copy_size_rtx));
@@ -4763,11 +4790,10 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
                                       copy_size_rtx, NULL_RTX, 0,
                                       OPTAB_LIB_WIDEN);
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-                 if (GET_MODE (copy_size_rtx) != Pmode)
-                   copy_size_rtx = convert_to_mode (Pmode, copy_size_rtx,
+                 if (GET_MODE (copy_size_rtx) != address_mode)
+                   copy_size_rtx = convert_to_mode (address_mode,
+                                                    copy_size_rtx,
                                                     TYPE_UNSIGNED (sizetype));
-#endif
 
                  target = offset_address (target, copy_size_rtx,
                                           highest_pow2_factor (copy_size));
@@ -5257,6 +5283,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
 
            if (offset)
              {
+               enum machine_mode address_mode;
                rtx offset_rtx;
 
                offset
@@ -5267,13 +5294,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                offset_rtx = expand_normal (offset);
                gcc_assert (MEM_P (to_rtx));
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-               if (GET_MODE (offset_rtx) != Pmode)
-                 offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-#else
-               if (GET_MODE (offset_rtx) != ptr_mode)
-                 offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-#endif
+               address_mode
+                 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (to_rtx));
+               if (GET_MODE (offset_rtx) != address_mode)
+                 offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
 
                to_rtx = offset_address (to_rtx, offset_rtx,
                                         highest_pow2_factor (offset));
@@ -6796,7 +6820,7 @@ expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
 
 static rtx
 expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
-                        enum expand_modifier modifier)
+                        enum expand_modifier modifier, addr_space_t as)
 {
   rtx result, subtarget;
   tree inner, offset;
@@ -6823,7 +6847,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
     case CONST_DECL:
       /* Recurse and make the output_constant_def clause above handle this.  */
       return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target,
-                                     tmode, modifier);
+                                     tmode, modifier, as);
 
     case REALPART_EXPR:
       /* The real part of the complex number is always first, therefore
@@ -6913,7 +6937,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
       TYPE_ALIGN (TREE_TYPE (inner)) = TYPE_ALIGN (TREE_TYPE (exp));
       TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
     }
-  result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier);
+  result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
 
   if (offset)
     {
@@ -6925,8 +6949,8 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
                         modifier == EXPAND_INITIALIZER
                          ? EXPAND_INITIALIZER : EXPAND_NORMAL);
 
-      result = convert_memory_address (tmode, result);
-      tmp = convert_memory_address (tmode, tmp);
+      result = convert_memory_address_addr_space (tmode, result, as);
+      tmp = convert_memory_address_addr_space (tmode, tmp, as);
 
       if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
        result = gen_rtx_PLUS (tmode, result, tmp);
@@ -6959,6 +6983,9 @@ static rtx
 expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
                       enum expand_modifier modifier)
 {
+  addr_space_t as = ADDR_SPACE_GENERIC;
+  enum machine_mode address_mode = Pmode;
+  enum machine_mode pointer_mode = ptr_mode;
   enum machine_mode rmode;
   rtx result;
 
@@ -6966,14 +6993,21 @@ expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
   if (tmode == VOIDmode)
     tmode = TYPE_MODE (TREE_TYPE (exp));
 
+  if (POINTER_TYPE_P (TREE_TYPE (exp)))
+    {
+      as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
+      address_mode = targetm.addr_space.address_mode (as);
+      pointer_mode = targetm.addr_space.pointer_mode (as);
+    }
+
   /* We can get called with some Weird Things if the user does silliness
      like "(short) &a".  In that case, convert_memory_address won't do
      the right thing, so ignore the given target mode.  */
-  if (tmode != Pmode && tmode != ptr_mode)
-    tmode = Pmode;
+  if (tmode != address_mode && tmode != pointer_mode)
+    tmode = address_mode;
 
   result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
-                                   tmode, modifier);
+                                   tmode, modifier, as);
 
   /* Despite expand_expr claims concerning ignoring TMODE when not
      strictly convenient, stuff breaks if we don't honor it.  Note
@@ -6982,7 +7016,7 @@ expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
   if (rmode == VOIDmode)
     rmode = tmode;
   if (rmode != tmode)
-    result = convert_memory_address (tmode, result);
+    result = convert_memory_address_addr_space (tmode, result, as);
 
   return result;
 }
@@ -8657,6 +8691,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       {
        tree exp1 = treeop0;
        addr_space_t as = ADDR_SPACE_GENERIC;
+       enum machine_mode address_mode = Pmode;
 
        if (modifier != EXPAND_WRITE)
          {
@@ -8668,7 +8703,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
          }
 
        if (POINTER_TYPE_P (TREE_TYPE (exp1)))
-         as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1)));
+         {
+           as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1)));
+           address_mode = targetm.addr_space.address_mode (as);
+         }
 
        op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
        op0 = memory_address_addr_space (mode, op0, as);
@@ -8676,7 +8714,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        if (code == ALIGN_INDIRECT_REF)
          {
            int align = TYPE_ALIGN_UNIT (type);
-           op0 = gen_rtx_AND (Pmode, op0, GEN_INT (-align));
+           op0 = gen_rtx_AND (address_mode, op0, GEN_INT (-align));
            op0 = memory_address_addr_space (mode, op0, as);
          }
 
@@ -8719,7 +8757,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        struct mem_address addr;
 
        get_address_description (exp, &addr);
-       op0 = addr_for_mem_ref (&addr, true);
+       op0 = addr_for_mem_ref (&addr, as, true);
        op0 = memory_address_addr_space (mode, op0, as);
        temp = gen_rtx_MEM (mode, op0);
        set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
@@ -9011,18 +9049,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
 
        if (offset)
          {
+           enum machine_mode address_mode;
            rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
                                          EXPAND_SUM);
 
            gcc_assert (MEM_P (op0));
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-           if (GET_MODE (offset_rtx) != Pmode)
-             offset_rtx = convert_to_mode (Pmode, offset_rtx, 0);
-#else
-           if (GET_MODE (offset_rtx) != ptr_mode)
-             offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
-#endif
+           address_mode
+             = targetm.addr_space.address_mode (MEM_ADDR_SPACE (op0));
+           if (GET_MODE (offset_rtx) != address_mode)
+             offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
 
            if (GET_MODE (op0) == BLKmode
                /* A constant address in OP0 can have VOIDmode, we must
index aab4fac..102929d 100644 (file)
@@ -206,15 +206,9 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
 {
   unsigned HOST_WIDE_INT low0 = l1;
   HOST_WIDE_INT high0 = h1;
-  unsigned int prec;
+  unsigned int prec = int_or_pointer_precision (type);
   int sign_extended_type;
 
-  if (POINTER_TYPE_P (type)
-      || TREE_CODE (type) == OFFSET_TYPE)
-    prec = POINTER_SIZE;
-  else
-    prec = TYPE_PRECISION (type);
-
   /* Size types *are* sign extended.  */
   sign_extended_type = (!TYPE_UNSIGNED (type)
                        || (TREE_CODE (type) == INTEGER_TYPE
index 8b1b450..d8d15a5 100644 (file)
@@ -1332,9 +1332,12 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)
       && if_info->branch_cost >= 5)
     {
+      enum machine_mode address_mode
+       = targetm.addr_space.address_mode (MEM_ADDR_SPACE (a));
+
       a = XEXP (a, 0);
       b = XEXP (b, 0);
-      x = gen_reg_rtx (Pmode);
+      x = gen_reg_rtx (address_mode);
       is_mem = 1;
     }
 
index 9e2b704..5d771d7 100644 (file)
@@ -626,7 +626,6 @@ extern void default_emit_except_table_label (FILE *);
 extern void default_internal_label (FILE *, const char *, unsigned long);
 extern void default_file_start (void);
 extern void file_end_indicate_exec_stack (void);
-extern bool default_valid_pointer_mode (enum machine_mode);
 
 extern void default_elf_asm_output_external (FILE *file, tree,
                                             const char *);
index 8937518..ac8350d 100644 (file)
@@ -247,7 +247,7 @@ kill_autoinc_value (rtx *px, void *data)
     {
       x = XEXP (x, 0);
       kill_value (x, vd);
-      set_value_regno (REGNO (x), Pmode, vd);
+      set_value_regno (REGNO (x), GET_MODE (x), vd);
       return -1;
     }
 
index 4d45d5d..581af4c 100644 (file)
@@ -185,7 +185,9 @@ try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
                   &SET_SRC (inc_insn_set),
                   XEXP (SET_SRC (inc_insn_set), 0), 1);
              validate_change (insn, &XEXP (use, 0),
-                              gen_rtx_fmt_e (inc_code, Pmode, reg), 1);
+                              gen_rtx_fmt_e (inc_code,
+                                             GET_MODE (XEXP (use, 0)), reg),
+                              1);
              if (apply_change_group ())
                {
                  /* If there is a REG_DEAD note on this insn, we must
index 166bcb9..3333697 100644 (file)
@@ -3987,12 +3987,15 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                 && MEM_P (recog_data.operand[i]))
          {
            /* If the address to be reloaded is a VOIDmode constant,
-              use Pmode as mode of the reload register, as would have
-              been done by find_reloads_address.  */
+              use the default address mode as mode of the reload register,
+              as would have been done by find_reloads_address.  */
            enum machine_mode address_mode;
            address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
            if (address_mode == VOIDmode)
-             address_mode = Pmode;
+             {
+               addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
+               address_mode = targetm.addr_space.address_mode (as);
+             }
 
            operand_reloadnum[i]
              = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
@@ -5113,7 +5116,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
             That will at least work.  */
          find_reloads_address_part (ad, loc,
                                     base_reg_class (mode, MEM, SCRATCH),
-                                    Pmode, opnum, type, ind_levels);
+                                    GET_MODE (ad), opnum, type, ind_levels);
        }
       return ! removed_and;
     }
@@ -5235,6 +5238,10 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
      into a register.  */
   if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
     {
+      enum machine_mode address_mode = GET_MODE (ad);
+      if (ad == VOIDmode)
+       address_mode = targetm.addr_space.address_mode (as);
+
       /* If AD is an address in the constant pool, the MEM rtx may be shared.
         Unshare it so we can safely alter it.  */
       if (memrefloc && GET_CODE (ad) == SYMBOL_REF
@@ -5247,7 +5254,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
        }
 
       find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH),
-                                Pmode, opnum, type, ind_levels);
+                                address_mode, opnum, type, ind_levels);
       return ! removed_and;
     }
 
@@ -5334,16 +5341,12 @@ subst_reg_equivs (rtx ad, rtx insn)
    This routine assumes both inputs are already in canonical form.  */
 
 rtx
-form_sum (rtx x, rtx y)
+form_sum (enum machine_mode mode, rtx x, rtx y)
 {
   rtx tem;
-  enum machine_mode mode = GET_MODE (x);
-
-  if (mode == VOIDmode)
-    mode = GET_MODE (y);
 
-  if (mode == VOIDmode)
-    mode = Pmode;
+  gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
+  gcc_assert (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode);
 
   if (CONST_INT_P (x))
     return plus_constant (y, INTVAL (x));
@@ -5353,12 +5356,12 @@ form_sum (rtx x, rtx y)
     tem = x, x = y, y = tem;
 
   if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
-    return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
+    return form_sum (mode, XEXP (x, 0), form_sum (mode, XEXP (x, 1), y));
 
   /* Note that if the operands of Y are specified in the opposite
      order in the recursive calls below, infinite recursion will occur.  */
   if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
-    return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
+    return form_sum (mode, form_sum (mode, x, XEXP (y, 0)), XEXP (y, 1));
 
   /* If both constant, encapsulate sum.  Otherwise, just form sum.  A
      constant will have been placed second.  */
@@ -5425,9 +5428,9 @@ subst_indexed_address (rtx addr)
 
       /* Compute the sum.  */
       if (op2 != 0)
-       op1 = form_sum (op1, op2);
+       op1 = form_sum (GET_MODE (addr), op1, op2);
       if (op1 != 0)
-       op0 = form_sum (op0, op1);
+       op0 = form_sum (GET_MODE (addr), op0, op1);
 
       return op0;
     }
@@ -5827,7 +5830,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
              rtx equiv = (MEM_P (XEXP (x, 0))
                           ? XEXP (x, 0)
                           : reg_equiv_mem[regno]);
-             int icode = (int) optab_handler (add_optab, Pmode)->insn_code;
+             int icode
+               = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
              if (insn && NONJUMP_INSN_P (insn) && equiv
                  && memory_operand (equiv, GET_MODE (equiv))
 #ifdef HAVE_cc0
@@ -5835,9 +5839,9 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 #endif
                  && ! (icode != CODE_FOR_nothing
                        && ((*insn_data[icode].operand[0].predicate)
-                           (equiv, Pmode))
+                           (equiv, GET_MODE (x)))
                        && ((*insn_data[icode].operand[1].predicate)
-                           (equiv, Pmode))))
+                           (equiv, GET_MODE (x)))))
                {
                  /* We use the original pseudo for loc, so that
                     emit_reload_insns() knows which pseudo this
index 3789680..5d8375b 100644 (file)
@@ -289,7 +289,7 @@ extern int find_reloads (rtx, int, int, int, short *);
    address, namely: sum constant integers, surround the sum of two
    constants with a CONST, put the constant as the second operand, and
    group the constant on the outermost sum.  */
-extern rtx form_sum (rtx, rtx);
+extern rtx form_sum (enum machine_mode, rtx, rtx);
 
 /* Substitute into the current INSN the registers into which we have reloaded
    the things that need reloading.  */
index 2c881e4..ce04922 100644 (file)
@@ -2658,7 +2658,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
                     && reg_equiv_constant[REGNO (new0)] != 0)
              new0 = reg_equiv_constant[REGNO (new0)];
 
-           new_rtx = form_sum (new0, new1);
+           new_rtx = form_sum (GET_MODE (x), new0, new1);
 
            /* As above, if we are not inside a MEM we do not want to
               turn a PLUS into something else.  We might try to do so here
index e9536b5..7cf3a7f 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1613,7 +1613,10 @@ extern unsigned int subreg_highpart_offset (enum machine_mode,
                                            enum machine_mode);
 extern int byte_lowpart_offset (enum machine_mode, enum machine_mode);
 extern rtx make_safe_from (rtx, rtx);
-extern rtx convert_memory_address (enum machine_mode, rtx);
+extern rtx convert_memory_address_addr_space (enum machine_mode, rtx,
+                                             addr_space_t);
+#define convert_memory_address(to_mode,x) \
+       convert_memory_address_addr_space ((to_mode), (x), ADDR_SPACE_GENERIC)
 extern rtx get_insns (void);
 extern const char *get_insn_name (int);
 extern rtx get_last_insn (void);
index 7da04f2..d14bbe5 100644 (file)
@@ -3748,7 +3748,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       /* If pointers extend unsigned and this is a pointer in Pmode, say that
         all the bits above ptr_mode are known to be zero.  */
-      if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
          && REG_POINTER (x))
        nonzero &= GET_MODE_MASK (ptr_mode);
 #endif
@@ -3985,7 +3989,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
        /* If pointers extend unsigned and this is an addition or subtraction
           to a pointer in Pmode, all the bits above ptr_mode are known to be
           zero.  */
-       if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
+       /* As we do not know which address space the pointer is refering to,
+          we can do this only if the target does not support different pointer
+          or address modes depending on the address space.  */
+       if (target_default_pointer_address_modes_p ()
+           && POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
            && (code == PLUS || code == MINUS)
            && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
          nonzero &= GET_MODE_MASK (ptr_mode);
@@ -4259,8 +4267,12 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       /* If pointers extend signed and this is a pointer in Pmode, say that
         all the bits above ptr_mode are known to be sign bit copies.  */
-      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
-         && REG_POINTER (x))
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+         && mode == Pmode && REG_POINTER (x))
        return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
 #endif
 
@@ -4456,7 +4468,11 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       /* If pointers extend signed and this is an addition or subtraction
         to a pointer in Pmode, all the bits above ptr_mode are known to be
         sign bit copies.  */
-      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
          && (code == PLUS || code == MINUS)
          && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
        result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
index 1fd484d..1f1a76c 100644 (file)
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "cselib.h"
 #include "ira.h"
+#include "target.h"
 
 #ifdef INSN_SCHEDULING
 
@@ -2281,8 +2282,11 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
 
       if (sched_deps_info->use_cselib)
        {
+         enum machine_mode address_mode
+           = targetm.addr_space.address_mode (MEM_ADDR_SPACE (dest));
+
          t = shallow_copy_rtx (dest);
-         cselib_lookup (XEXP (t, 0), Pmode, 1);
+         cselib_lookup (XEXP (t, 0), address_mode, 1);
          XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
        }
       t = canon_rtx (t);
@@ -2435,8 +2439,11 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
 
        if (sched_deps_info->use_cselib)
          {
+           enum machine_mode address_mode
+             = targetm.addr_space.address_mode (MEM_ADDR_SPACE (t));
+
            t = shallow_copy_rtx (t);
-           cselib_lookup (XEXP (t, 0), Pmode, 1);
+           cselib_lookup (XEXP (t, 0), address_mode, 1);
            XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
          }
 
index 5fce7cf..b307f52 100644 (file)
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 #include "basic-block.h"
 #include "cselib.h"
+#include "target.h"
 
 #ifdef INSN_SCHEDULING
 #include "sel-sched-ir.h"
@@ -931,10 +932,13 @@ rtx
 debug_mem_addr_value (rtx x)
 {
   rtx t, addr;
+  enum machine_mode address_mode;
 
   gcc_assert (MEM_P (x));
+  address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+
   t = shallow_copy_rtx (x);
-  if (cselib_lookup (XEXP (t, 0), Pmode, 0))
+  if (cselib_lookup (XEXP (t, 0), address_mode, 0))
     XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
 
   t = canon_rtx (t);
index 926615e..39a791d 100644 (file)
@@ -1012,7 +1012,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
        return rtl_hooks.gen_lowpart_no_emit (mode, op);
 
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
-      if (! POINTERS_EXTEND_UNSIGNED
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && ! POINTERS_EXTEND_UNSIGNED
          && mode == Pmode && GET_MODE (op) == ptr_mode
          && (CONSTANT_P (op)
              || (GET_CODE (op) == SUBREG
@@ -1034,7 +1038,11 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
        return rtl_hooks.gen_lowpart_no_emit (mode, op);
 
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
-      if (POINTERS_EXTEND_UNSIGNED > 0
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && POINTERS_EXTEND_UNSIGNED > 0
          && mode == Pmode && GET_MODE (op) == ptr_mode
          && (CONSTANT_P (op)
              || (GET_CODE (op) == SUBREG
index d070b10..e512db8 100644 (file)
@@ -52,9 +52,9 @@ unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNI
 /* ... and its original value in bytes, specified via -fpack-struct=<value>.  */
 unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT;
 
-/* Nonzero if all REFERENCE_TYPEs are internal and hence should be
-   allocated in Pmode, not ptr_mode.   Set only by internal_reference_types
-   called only by a front end.  */
+/* Nonzero if all REFERENCE_TYPEs are internal and hence should be allocated
+   in the address spaces' address_mode, not pointer_mode.   Set only by
+   internal_reference_types called only by a front end.  */
 static int reference_types_internal = 0;
 
 static tree self_referential_size (tree);
@@ -71,8 +71,8 @@ extern void debug_rli (record_layout_info);
 
 static GTY(()) tree pending_sizes;
 
-/* Show that REFERENCE_TYPES are internal and should be Pmode.  Called only
-   by front end.  */
+/* Show that REFERENCE_TYPES are internal and should use address_mode.
+   Called only by front end.  */
 
 void
 internal_reference_types (void)
@@ -1917,6 +1917,7 @@ layout_type (tree type)
       /* A pointer might be MODE_PARTIAL_INT,
         but ptrdiff_t must be integral.  */
       SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
+      TYPE_PRECISION (type) = POINTER_SIZE;
       break;
 
     case FUNCTION_TYPE:
@@ -1932,16 +1933,17 @@ layout_type (tree type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-       enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
-                                  && reference_types_internal)
-                                 ? Pmode : TYPE_MODE (type));
-
-       int nbits = GET_MODE_BITSIZE (mode);
+       enum machine_mode mode = TYPE_MODE (type);
+       if (TREE_CODE (type) == REFERENCE_TYPE && reference_types_internal)
+         {
+           addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+           mode = targetm.addr_space.address_mode (as);
+         }
 
-       TYPE_SIZE (type) = bitsize_int (nbits);
+       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
        TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
        TYPE_UNSIGNED (type) = 1;
-       TYPE_PRECISION (type) = nbits;
+       TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
       }
       break;
 
index fae4210..547a5fb 100644 (file)
 #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
 
 #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,                        \
index 5b296d5..a243bcd 100644 (file)
@@ -68,6 +68,12 @@ typedef int (* print_switch_fn_type) (print_switch_type, const char *);
 /* An example implementation for ELF targets.  Defined in varasm.c  */
 extern int elf_record_gcc_switches (print_switch_type type, const char *);
 
+/* Some places still assume that all pointer or address modes are the
+   standard Pmode and ptr_mode.  These optimizations become invalid if
+   the target actually supports multiple different modes.  For now,
+   we disable such optimizations on such targets, using this function.  */
+extern bool target_default_pointer_address_modes_p (void);
+
 struct stdarg_info;
 struct spec_info_def;
 
@@ -696,6 +702,16 @@ struct gcc_target
 
   /* Support for named address spaces.  */
   struct addr_space {
+    /* MODE to use for a pointer into another address space.  */
+    enum machine_mode (* pointer_mode) (addr_space_t);
+
+    /* MODE to use for an address in another address space.  */
+    enum machine_mode (* address_mode) (addr_space_t);
+
+    /* True if MODE is valid for a pointer in __attribute__((mode("MODE")))
+       in another address space.  */
+    bool (* valid_pointer_mode) (enum machine_mode, addr_space_t);
+
     /* True if an address is a valid memory address to a given named address
        space for a given mode.  */
     bool (* legitimate_address_p) (enum machine_mode, rtx, bool, addr_space_t);
index ab9c05b..35ed9ee 100644 (file)
@@ -831,6 +831,62 @@ default_builtin_support_vector_misalignment (enum machine_mode mode,
   return false;
 }
 
+/* Determine whether or not a pointer mode is valid. Assume defaults
+   of ptr_mode or Pmode - can be overridden.  */
+bool
+default_valid_pointer_mode (enum machine_mode mode)
+{
+  return (mode == ptr_mode || mode == Pmode);
+}
+
+/* Return the mode for a pointer to a given ADDRSPACE, defaulting to ptr_mode
+   for the generic address space only.  */
+
+enum machine_mode
+default_addr_space_pointer_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
+{
+  gcc_assert (ADDR_SPACE_GENERIC_P (addrspace));
+  return ptr_mode;
+}
+
+/* Return the mode for an address in a given ADDRSPACE, defaulting to Pmode
+   for the generic address space only.  */
+
+enum machine_mode
+default_addr_space_address_mode (addr_space_t addrspace ATTRIBUTE_UNUSED)
+{
+  gcc_assert (ADDR_SPACE_GENERIC_P (addrspace));
+  return Pmode;
+}
+
+/* Named address space version of valid_pointer_mode.  */
+
+bool
+default_addr_space_valid_pointer_mode (enum machine_mode mode, addr_space_t as)
+{
+  if (!ADDR_SPACE_GENERIC_P (as))
+    return (mode == targetm.addr_space.pointer_mode (as)
+           || mode == targetm.addr_space.address_mode (as));
+
+  return targetm.valid_pointer_mode (mode);
+}
+
+/* Some places still assume that all pointer or address modes are the
+   standard Pmode and ptr_mode.  These optimizations become invalid if
+   the target actually supports multiple different modes.  For now,
+   we disable such optimizations on such targets, using this function.  */
+
+bool
+target_default_pointer_address_modes_p (void)
+{
+  if (targetm.addr_space.address_mode != default_addr_space_address_mode)
+    return false;
+  if (targetm.addr_space.pointer_mode != default_addr_space_pointer_mode)
+    return false;
+
+  return true;
+}
+
 /* Named address space version of legitimate_address_p.  */
 
 bool
index eedc52b..cbbbee8 100644 (file)
@@ -119,6 +119,11 @@ extern bool default_hard_regno_scratch_ok (unsigned int);
 extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
 extern bool default_target_option_pragma_parse (tree, tree);
 extern bool default_target_can_inline_p (tree, tree);
+extern bool default_valid_pointer_mode (enum machine_mode);
+extern enum machine_mode default_addr_space_pointer_mode (addr_space_t);
+extern enum machine_mode default_addr_space_address_mode (addr_space_t);
+extern bool default_addr_space_valid_pointer_mode (enum machine_mode,
+                                                  addr_space_t);
 extern bool default_addr_space_legitimate_address_p (enum machine_mode, rtx,
                                                     bool, addr_space_t);
 extern rtx default_addr_space_legitimize_address (rtx, rtx, enum machine_mode,
index ca1e06a..a701569 100644 (file)
@@ -922,7 +922,7 @@ struct mem_address
 struct affine_tree_combination;
 tree create_mem_ref (gimple_stmt_iterator *, tree, 
                     struct affine_tree_combination *, bool);
-rtx addr_for_mem_ref (struct mem_address *, bool);
+rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
 void get_address_description (tree, struct mem_address *);
 tree maybe_fold_tmr (tree);
 
index c5e3422..1428803 100644 (file)
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "expr.h"
 #include "ggc.h"
 #include "tree-affine.h"
+#include "target.h"
 
 /* TODO -- handling of symbols (according to Richard Hendersons
    comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
@@ -70,32 +71,38 @@ along with GCC; see the file COPYING3.  If not see
 /* A "template" for memory address, used to determine whether the address is
    valid for mode.  */
 
-struct GTY (()) mem_addr_template {
+typedef struct GTY (()) mem_addr_template {
   rtx ref;                     /* The template.  */
   rtx * GTY ((skip)) step_p;   /* The point in template where the step should be
                                   filled in.  */
   rtx * GTY ((skip)) off_p;    /* The point in template where the offset should
                                   be filled in.  */
-};
+} mem_addr_template;
 
-/* The templates.  Each of the five bits of the index corresponds to one
-   component of TARGET_MEM_REF being present, see TEMPL_IDX.  */
+DEF_VEC_O (mem_addr_template);
+DEF_VEC_ALLOC_O (mem_addr_template, gc);
 
-static GTY (()) struct mem_addr_template templates[32];
+/* The templates.  Each of the low five bits of the index corresponds to one
+   component of TARGET_MEM_REF being present, while the high bits identify
+   the address space.  See TEMPL_IDX.  */
 
-#define TEMPL_IDX(SYMBOL, BASE, INDEX, STEP, OFFSET) \
-  (((SYMBOL != 0) << 4) \
+static GTY(()) VEC (mem_addr_template, gc) *mem_addr_template_list;
+
+#define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
+  (((int) (AS) << 5) \
+   | ((SYMBOL != 0) << 4) \
    | ((BASE != 0) << 3) \
    | ((INDEX != 0) << 2) \
    | ((STEP != 0) << 1) \
    | (OFFSET != 0))
 
 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
-   STEP and OFFSET to *ADDR.  Stores pointers to where step is placed to
-   *STEP_P and offset to *OFFSET_P.  */
+   STEP and OFFSET to *ADDR using address mode ADDRESS_MODE.  Stores pointers
+   to where step is placed to *STEP_P and offset to *OFFSET_P.  */
 
 static void
-gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
+gen_addr_rtx (enum machine_mode address_mode,
+             rtx symbol, rtx base, rtx index, rtx step, rtx offset,
              rtx *addr, rtx **step_p, rtx **offset_p)
 {
   rtx act_elem;
@@ -111,7 +118,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
       act_elem = index;
       if (step)
        {
-         act_elem = gen_rtx_MULT (Pmode, act_elem, step);
+         act_elem = gen_rtx_MULT (address_mode, act_elem, step);
 
          if (step_p)
            *step_p = &XEXP (act_elem, 1);
@@ -123,7 +130,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
   if (base)
     {
       if (*addr)
-       *addr = simplify_gen_binary (PLUS, Pmode, base, *addr);
+       *addr = simplify_gen_binary (PLUS, address_mode, base, *addr);
       else
        *addr = base;
     }
@@ -133,7 +140,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
       act_elem = symbol;
       if (offset)
        {
-         act_elem = gen_rtx_PLUS (Pmode, act_elem, offset);
+         act_elem = gen_rtx_PLUS (address_mode, act_elem, offset);
 
          if (offset_p)
            *offset_p = &XEXP (act_elem, 1);
@@ -141,11 +148,11 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
          if (GET_CODE (symbol) == SYMBOL_REF
              || GET_CODE (symbol) == LABEL_REF
              || GET_CODE (symbol) == CONST)
-           act_elem = gen_rtx_CONST (Pmode, act_elem);
+           act_elem = gen_rtx_CONST (address_mode, act_elem);
        }
 
       if (*addr)
-       *addr = gen_rtx_PLUS (Pmode, *addr, act_elem);
+       *addr = gen_rtx_PLUS (address_mode, *addr, act_elem);
       else
        *addr = act_elem;
     }
@@ -153,7 +160,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
     {
       if (*addr)
        {
-         *addr = gen_rtx_PLUS (Pmode, *addr, offset);
+         *addr = gen_rtx_PLUS (address_mode, *addr, offset);
          if (offset_p)
            *offset_p = &XEXP (*addr, 1);
        }
@@ -169,55 +176,64 @@ gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
     *addr = const0_rtx;
 }
 
-/* Returns address for TARGET_MEM_REF with parameters given by ADDR.
+/* Returns address for TARGET_MEM_REF with parameters given by ADDR
+   in address space AS.
    If REALLY_EXPAND is false, just make fake registers instead 
    of really expanding the operands, and perform the expansion in-place
    by using one of the "templates".  */
 
 rtx
-addr_for_mem_ref (struct mem_address *addr, bool really_expand)
+addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
+                 bool really_expand)
 {
+  enum machine_mode address_mode = targetm.addr_space.address_mode (as);
   rtx address, sym, bse, idx, st, off;
-  static bool templates_initialized = false;
   struct mem_addr_template *templ;
 
   if (addr->step && !integer_onep (addr->step))
     st = immed_double_const (TREE_INT_CST_LOW (addr->step),
-                            TREE_INT_CST_HIGH (addr->step), Pmode);
+                            TREE_INT_CST_HIGH (addr->step), address_mode);
   else
     st = NULL_RTX;
 
   if (addr->offset && !integer_zerop (addr->offset))
     off = immed_double_const (TREE_INT_CST_LOW (addr->offset),
-                             TREE_INT_CST_HIGH (addr->offset), Pmode);
+                             TREE_INT_CST_HIGH (addr->offset), address_mode);
   else
     off = NULL_RTX;
 
   if (!really_expand)
     {
+      unsigned int templ_index
+       = TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off);
+
+      if (templ_index
+         >= VEC_length (mem_addr_template, mem_addr_template_list))
+       VEC_safe_grow_cleared (mem_addr_template, gc, mem_addr_template_list,
+                              templ_index + 1);
+
       /* Reuse the templates for addresses, so that we do not waste memory.  */
-      if (!templates_initialized)
+      templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index);
+      if (!templ->ref)
        {
-         unsigned i;
-
-         templates_initialized = true;
-         sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup ("test_symbol"));
-         bse = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
-         idx = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2);
-
-         for (i = 0; i < 32; i++)
-           gen_addr_rtx ((i & 16 ? sym : NULL_RTX),
-                         (i & 8 ? bse : NULL_RTX),
-                         (i & 4 ? idx : NULL_RTX),
-                         (i & 2 ? const0_rtx : NULL_RTX),
-                         (i & 1 ? const0_rtx : NULL_RTX),
-                         &templates[i].ref,
-                         &templates[i].step_p,
-                         &templates[i].off_p);
+         sym = (addr->symbol ?
+                gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol"))
+                : NULL_RTX);
+         bse = (addr->base ?
+                gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1)
+                : NULL_RTX);
+         idx = (addr->index ?
+                gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2)
+                : NULL_RTX);
+
+         gen_addr_rtx (address_mode, sym, bse, idx,
+                       st? const0_rtx : NULL_RTX,
+                       off? const0_rtx : NULL_RTX,
+                       &templ->ref,
+                       &templ->step_p,
+                       &templ->off_p);
        }
 
-      templ = templates + TEMPL_IDX (addr->symbol, addr->base, addr->index,
-                                    st, off);
       if (st)
        *templ->step_p = st;
       if (off)
@@ -229,16 +245,16 @@ addr_for_mem_ref (struct mem_address *addr, bool really_expand)
   /* Otherwise really expand the expressions.  */
   sym = (addr->symbol
         ? expand_expr (build_addr (addr->symbol, current_function_decl),
-                       NULL_RTX, Pmode, EXPAND_NORMAL)
+                       NULL_RTX, address_mode, EXPAND_NORMAL)
         : NULL_RTX);
   bse = (addr->base
-        ? expand_expr (addr->base, NULL_RTX, Pmode, EXPAND_NORMAL)
+        ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL)
         : NULL_RTX);
   idx = (addr->index
-        ? expand_expr (addr->index, NULL_RTX, Pmode, EXPAND_NORMAL)
+        ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL)
         : NULL_RTX);
 
-  gen_addr_rtx (sym, bse, idx, st, off, &address, NULL, NULL);
+  gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL);
   return address;
 }
 
@@ -310,7 +326,7 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as,
 {
   rtx address;
 
-  address = addr_for_mem_ref (addr, false);
+  address = addr_for_mem_ref (addr, as, false);
   if (!address)
     return false;
 
index 7e53613..82e45d2 100644 (file)
@@ -2643,13 +2643,14 @@ static rtx
 produce_memory_decl_rtl (tree obj, int *regno)
 {
   addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (obj));
+  enum machine_mode address_mode = targetm.addr_space.address_mode (as);
   rtx x;
   
   gcc_assert (obj);
   if (TREE_STATIC (obj) || DECL_EXTERNAL (obj))
     {
       const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));
-      x = gen_rtx_SYMBOL_REF (Pmode, name);
+      x = gen_rtx_SYMBOL_REF (address_mode, name);
       SET_SYMBOL_REF_DECL (x, obj);
       x = gen_rtx_MEM (DECL_MODE (obj), x);
       set_mem_addr_space (x, as);
@@ -2657,7 +2658,7 @@ produce_memory_decl_rtl (tree obj, int *regno)
     }
   else
     {
-      x = gen_raw_REG (Pmode, (*regno)++);
+      x = gen_raw_REG (address_mode, (*regno)++);
       x = gen_rtx_MEM (DECL_MODE (obj), x);
       set_mem_addr_space (x, as);
     }
@@ -3045,16 +3046,17 @@ multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, enum machine_mode mode,
   valid_mult = VEC_index (sbitmap, valid_mult_list, data_index);
   if (!valid_mult)
     {
-      rtx reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
+      enum machine_mode address_mode = targetm.addr_space.address_mode (as);
+      rtx reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
       rtx addr;
       HOST_WIDE_INT i;
 
       valid_mult = sbitmap_alloc (2 * MAX_RATIO + 1);
       sbitmap_zero (valid_mult);
-      addr = gen_rtx_fmt_ee (MULT, Pmode, reg1, NULL_RTX);
+      addr = gen_rtx_fmt_ee (MULT, address_mode, reg1, NULL_RTX);
       for (i = -MAX_RATIO; i <= MAX_RATIO; i++)
        {
-         XEXP (addr, 1) = gen_int_mode (i, Pmode);
+         XEXP (addr, 1) = gen_int_mode (i, address_mode);
          if (memory_address_addr_space_p (mode, addr, as))
            SET_BIT (valid_mult, i + MAX_RATIO);
        }
@@ -3108,6 +3110,7 @@ get_address_cost (bool symbol_present, bool var_present,
                  addr_space_t as, bool speed,
                  bool stmt_after_inc, bool *may_autoinc)
 {
+  enum machine_mode address_mode = targetm.addr_space.address_mode (as);
   static VEC(address_cost_data, heap) *address_cost_data_list;
   unsigned int data_index = (int) as * MAX_MACHINE_MODE + (int) mem_mode;
   address_cost_data data;
@@ -3136,12 +3139,12 @@ get_address_cost (bool symbol_present, bool var_present,
 
       data = (address_cost_data) xcalloc (1, sizeof (*data));
 
-      reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
+      reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
 
-      addr = gen_rtx_fmt_ee (PLUS, Pmode, reg1, NULL_RTX);
+      addr = gen_rtx_fmt_ee (PLUS, address_mode, reg1, NULL_RTX);
       for (i = start; i <= 1 << 20; i <<= 1)
        {
-         XEXP (addr, 1) = gen_int_mode (i, Pmode);
+         XEXP (addr, 1) = gen_int_mode (i, address_mode);
          if (!memory_address_addr_space_p (mem_mode, addr, as))
            break;
        }
@@ -3150,7 +3153,7 @@ get_address_cost (bool symbol_present, bool var_present,
 
       for (i = start; i <= 1 << 20; i <<= 1)
        {
-         XEXP (addr, 1) = gen_int_mode (-i, Pmode);
+         XEXP (addr, 1) = gen_int_mode (-i, address_mode);
          if (!memory_address_addr_space_p (mem_mode, addr, as))
            break;
        }
@@ -3177,30 +3180,30 @@ get_address_cost (bool symbol_present, bool var_present,
 
       /* Compute the cost of various addressing modes.  */
       acost = 0;
-      reg0 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
-      reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2);
+      reg0 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
+      reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2);
 
       if (HAVE_PRE_DECREMENT)
        {
-         addr = gen_rtx_PRE_DEC (Pmode, reg0);
+         addr = gen_rtx_PRE_DEC (address_mode, reg0);
          has_predec[mem_mode]
            = memory_address_addr_space_p (mem_mode, addr, as);
        }
       if (HAVE_POST_DECREMENT)
        {
-         addr = gen_rtx_POST_DEC (Pmode, reg0);
+         addr = gen_rtx_POST_DEC (address_mode, reg0);
          has_postdec[mem_mode]
            = memory_address_addr_space_p (mem_mode, addr, as);
        }
       if (HAVE_PRE_INCREMENT)
        {
-         addr = gen_rtx_PRE_INC (Pmode, reg0);
+         addr = gen_rtx_PRE_INC (address_mode, reg0);
          has_preinc[mem_mode]
            = memory_address_addr_space_p (mem_mode, addr, as);
        }
       if (HAVE_POST_INCREMENT)
        {
-         addr = gen_rtx_POST_INC (Pmode, reg0);
+         addr = gen_rtx_POST_INC (address_mode, reg0);
          has_postinc[mem_mode]
            = memory_address_addr_space_p (mem_mode, addr, as);
        }
@@ -3213,15 +3216,15 @@ get_address_cost (bool symbol_present, bool var_present,
 
          addr = reg0;
          if (rat_p)
-           addr = gen_rtx_fmt_ee (MULT, Pmode, addr,
-                                  gen_int_mode (rat, Pmode));
+           addr = gen_rtx_fmt_ee (MULT, address_mode, addr,
+                                  gen_int_mode (rat, address_mode));
 
          if (var_p)
-           addr = gen_rtx_fmt_ee (PLUS, Pmode, addr, reg1);
+           addr = gen_rtx_fmt_ee (PLUS, address_mode, addr, reg1);
 
          if (sym_p)
            {
-             base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (""));
+             base = gen_rtx_SYMBOL_REF (address_mode, ggc_strdup (""));
              /* ??? We can run into trouble with some backends by presenting
                 it with symbols which haven't been properly passed through
                 targetm.encode_section_info.  By setting the local bit, we
@@ -3229,18 +3232,18 @@ get_address_cost (bool symbol_present, bool var_present,
              SYMBOL_REF_FLAGS (base) = SYMBOL_FLAG_LOCAL;
 
              if (off_p)
-               base = gen_rtx_fmt_e (CONST, Pmode,
+               base = gen_rtx_fmt_e (CONST, address_mode,
                                      gen_rtx_fmt_ee
-                                       (PLUS, Pmode, base,
-                                        gen_int_mode (off, Pmode)));
+                                       (PLUS, address_mode, base,
+                                        gen_int_mode (off, address_mode)));
            }
          else if (off_p)
-           base = gen_int_mode (off, Pmode);
+           base = gen_int_mode (off, address_mode);
          else
            base = NULL_RTX;
     
          if (base)
-           addr = gen_rtx_fmt_ee (PLUS, Pmode, addr, base);
+           addr = gen_rtx_fmt_ee (PLUS, address_mode, addr, base);
 
          start_sequence ();
          /* To avoid splitting addressing modes, pretend that no cse will
@@ -3272,7 +3275,7 @@ get_address_cost (bool symbol_present, bool var_present,
         If VAR_PRESENT is true, try whether the mode with
         SYMBOL_PRESENT = false is cheaper even with cost of addition, and
         if this is the case, use it.  */
-      add_c = add_cost (Pmode, speed);
+      add_c = add_cost (address_mode, speed);
       for (i = 0; i < 8; i++)
        {
          var_p = i & 1;
@@ -3321,7 +3324,7 @@ get_address_cost (bool symbol_present, bool var_present,
                   data_index, data);
     }
 
-  bits = GET_MODE_BITSIZE (Pmode);
+  bits = GET_MODE_BITSIZE (address_mode);
   mask = ~(~(unsigned HOST_WIDE_INT) 0 << (bits - 1) << 1);
   offset &= mask;
   if ((offset >> (bits - 1) & 1))
@@ -3353,10 +3356,10 @@ get_address_cost (bool symbol_present, bool var_present,
             && multiplier_allowed_in_address_p (ratio, mem_mode, as));
 
   if (ratio != 1 && !ratio_p)
-    cost += multiply_by_cost (ratio, Pmode, speed);
+    cost += multiply_by_cost (ratio, address_mode, speed);
 
   if (s_offset && !offset_p && !symbol_present)
-    cost += add_cost (Pmode, speed);
+    cost += add_cost (address_mode, speed);
 
   if (may_autoinc)
     *may_autoinc = autoinc;
index c3570d3..ea3a508 100644 (file)
@@ -2376,7 +2376,9 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
   if (!alias_sets_conflict_p (get_deref_alias_set (vect_ptr),
                              get_alias_set (DR_REF (dr))))
     {
-      vect_ptr_type = build_pointer_type_for_mode (vectype, ptr_mode, true);
+      vect_ptr_type
+       = build_pointer_type_for_mode (vectype,
+                                      TYPE_MODE (vect_ptr_type), true);
       vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
                                        get_name (base_name));
     }
@@ -2392,7 +2394,8 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
                                      get_alias_set (lhs)))
            {
              vect_ptr_type
-               = build_pointer_type_for_mode (vectype, ptr_mode, true);
+               = build_pointer_type_for_mode (vectype,
+                                              TYPE_MODE (vect_ptr_type), true);
              vect_ptr
                = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
                                         get_name (base_name));
index dfc8807..4343415 100644 (file)
@@ -1684,8 +1684,7 @@ integer_pow2p (const_tree expr)
   if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
 
-  prec = (POINTER_TYPE_P (TREE_TYPE (expr))
-         ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
+  prec = int_or_pointer_precision (TREE_TYPE (expr));
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
 
@@ -1749,9 +1748,7 @@ tree_log2 (const_tree expr)
   if (TREE_CODE (expr) == COMPLEX_CST)
     return tree_log2 (TREE_REALPART (expr));
 
-  prec = (POINTER_TYPE_P (TREE_TYPE (expr))
-         ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
-
+  prec = int_or_pointer_precision (TREE_TYPE (expr));
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
 
@@ -1787,9 +1784,7 @@ tree_floor_log2 (const_tree expr)
   if (TREE_CODE (expr) == COMPLEX_CST)
     return tree_log2 (TREE_REALPART (expr));
 
-  prec = (POINTER_TYPE_P (TREE_TYPE (expr))
-         ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
-
+  prec = int_or_pointer_precision (TREE_TYPE (expr));
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
 
@@ -6746,7 +6741,10 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
 tree
 build_pointer_type (tree to_type)
 {
-  return build_pointer_type_for_mode (to_type, ptr_mode, false);
+  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
+                                             : TYPE_ADDR_SPACE (to_type);
+  enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  return build_pointer_type_for_mode (to_type, pointer_mode, false);
 }
 
 /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE.  */
@@ -6810,7 +6808,10 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode,
 tree
 build_reference_type (tree to_type)
 {
-  return build_reference_type_for_mode (to_type, ptr_mode, false);
+  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
+                                             : TYPE_ADDR_SPACE (to_type);
+  enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+  return build_reference_type_for_mode (to_type, pointer_mode, false);
 }
 
 /* Build a type that is compatible with t but has no cv quals anywhere
@@ -9675,7 +9676,19 @@ signed_or_unsigned_type_for (int unsignedp, tree type)
 {
   tree t = type;
   if (POINTER_TYPE_P (type))
-    t = size_type_node;
+    {
+      /* If the pointer points to the normal address space, use the
+        size_type_node.  Otherwise use an appropriate size for the pointer
+        based on the named address space it points to.  */
+      if (!TYPE_ADDR_SPACE (TREE_TYPE (t)))
+       t = size_type_node;
+
+      else
+       {
+         int prec = int_or_pointer_precision (t);
+         return lang_hooks.types.type_for_size (prec, unsignedp);
+       }
+    }
 
   if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
     return t;
@@ -10549,6 +10562,41 @@ build_target_option_node (void)
   return t;
 }
 
+/* Return the size in bits of an integer or pointer type.  TYPE_PRECISION
+   contains the bits, but in the past it was not set in some cases and there
+   was special purpose code that checked for POINTER_TYPE_P or OFFSET_TYPE, so
+   check that it is consitant when assertion checking is used.  */
+
+unsigned int
+int_or_pointer_precision (const_tree type)
+{
+#if ENABLE_ASSERT_CHECKING
+  unsigned int prec;
+
+  if (POINTER_TYPE_P (type))
+    {
+      addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+      prec = GET_MODE_BITSIZE (targetm.addr_space.pointer_mode (as));
+      gcc_assert (prec == TYPE_PRECISION (type));
+    }
+  else if (TREE_CODE (type) == OFFSET_TYPE)
+    {
+      prec = POINTER_SIZE;
+      gcc_assert (prec == TYPE_PRECISION (type));
+    }
+  else
+    {
+      prec = TYPE_PRECISION (type);
+      gcc_assert (prec != 0);
+    }
+
+  return prec;
+
+#else
+  return TYPE_PRECISION (type);
+#endif
+}
+
 /* Determine the "ultimate origin" of a block.  The block may be an inlined
    instance of an inlined instance of a block which is local to an inline
    function, so we have to trace all of the way back through the origin chain
index ad810b0..36deb0d 100644 (file)
@@ -4703,6 +4703,7 @@ extern const char *get_name (tree);
 extern bool stdarg_p (tree);
 extern bool prototype_p (tree);
 extern bool auto_var_in_fn_p (const_tree, const_tree);
+extern unsigned int int_or_pointer_precision (const_tree);
 extern tree build_low_bits_mask (tree, unsigned);
 extern tree tree_strip_nop_conversions (tree);
 extern tree tree_strip_sign_nop_conversions (tree);
index cfcc839..9fa1921 100644 (file)
@@ -4359,7 +4359,9 @@ replace_expr_with_values (rtx loc)
     return NULL;
   else if (MEM_P (loc))
     {
-      cselib_val *addr = cselib_lookup (XEXP (loc, 0), Pmode, 0);
+      enum machine_mode address_mode
+       = targetm.addr_space.address_mode (MEM_ADDR_SPACE (loc));
+      cselib_val *addr = cselib_lookup (XEXP (loc, 0), address_mode, 0);
       if (addr)
        return replace_equiv_address_nv (loc, addr->val_rtx);
       else
@@ -4493,7 +4495,9 @@ count_uses (rtx *loc, void *cuip)
          if (MEM_P (*loc)
              && !REG_P (XEXP (*loc, 0)) && !MEM_P (XEXP (*loc, 0)))
            {
-             val = cselib_lookup (XEXP (*loc, 0), Pmode, false);
+             enum machine_mode address_mode
+               = targetm.addr_space.address_mode (MEM_ADDR_SPACE (*loc));
+             val = cselib_lookup (XEXP (*loc, 0), address_mode, false);
 
              if (val && !cselib_preserved_value_p (val))
                {
@@ -4613,7 +4617,10 @@ add_uses (rtx *loc, void *data)
              && !REG_P (XEXP (vloc, 0)) && !MEM_P (XEXP (vloc, 0)))
            {
              rtx mloc = vloc;
-             cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
+             enum machine_mode address_mode
+               = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
+             cselib_val *val
+               = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
 
              if (val && !cselib_preserved_value_p (val))
                {
@@ -4624,7 +4631,8 @@ add_uses (rtx *loc, void *data)
                  cselib_preserve_value (val);
                  mo->type = MO_VAL_USE;
                  mloc = cselib_subst_to_values (XEXP (mloc, 0));
-                 mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
+                 mo->u.loc = gen_rtx_CONCAT (address_mode,
+                                             val->val_rtx, mloc);
                  if (dump_file && (dump_flags & TDF_DETAILS))
                    log_op_type (mo->u.loc, cui->bb, cui->insn,
                                 mo->type, dump_file);
@@ -4680,7 +4688,10 @@ add_uses (rtx *loc, void *data)
              && !REG_P (XEXP (oloc, 0)) && !MEM_P (XEXP (oloc, 0)))
            {
              rtx mloc = oloc;
-             cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
+             enum machine_mode address_mode
+               = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
+             cselib_val *val
+               = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
 
              if (val && !cselib_preserved_value_p (val))
                {
@@ -4691,7 +4702,8 @@ add_uses (rtx *loc, void *data)
                  cselib_preserve_value (val);
                  mo->type = MO_VAL_USE;
                  mloc = cselib_subst_to_values (XEXP (mloc, 0));
-                 mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
+                 mo->u.loc = gen_rtx_CONCAT (address_mode,
+                                             val->val_rtx, mloc);
                  mo->insn = cui->insn;
                  if (dump_file && (dump_flags & TDF_DETAILS))
                    log_op_type (mo->u.loc, cui->bb, cui->insn,
@@ -4824,14 +4836,16 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
          && !REG_P (XEXP (loc, 0)) && !MEM_P (XEXP (loc, 0)))
        {
          rtx mloc = loc;
-         cselib_val *val = cselib_lookup (XEXP (mloc, 0), Pmode, 0);
+         enum machine_mode address_mode
+           = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mloc));
+         cselib_val *val = cselib_lookup (XEXP (mloc, 0), address_mode, 0);
 
          if (val && !cselib_preserved_value_p (val))
            {
              cselib_preserve_value (val);
              mo->type = MO_VAL_USE;
              mloc = cselib_subst_to_values (XEXP (mloc, 0));
-             mo->u.loc = gen_rtx_CONCAT (Pmode, val->val_rtx, mloc);
+             mo->u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc);
              mo->insn = cui->insn;
              if (dump_file && (dump_flags & TDF_DETAILS))
                log_op_type (mo->u.loc, cui->bb, cui->insn,
index 95239b2..b6ff4ae 100644 (file)
@@ -1447,7 +1447,15 @@ make_decl_rtl (tree decl)
   if (use_object_blocks_p () && use_blocks_for_decl_p (decl))
     x = create_block_symbol (name, get_block_for_decl (decl), -1);
   else
-    x = gen_rtx_SYMBOL_REF (Pmode, name);
+    {
+      enum machine_mode address_mode = Pmode;
+      if (TREE_TYPE (decl) != error_mark_node)
+       {
+         addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
+         address_mode = targetm.addr_space.address_mode (as);
+       }
+      x = gen_rtx_SYMBOL_REF (address_mode, name);
+    }
   SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
   SET_SYMBOL_REF_DECL (x, decl);
 
@@ -4315,7 +4323,8 @@ initializer_constant_valid_p (tree value, tree endtype)
     case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       if (! INTEGRAL_TYPE_P (endtype)
-         || TYPE_PRECISION (endtype) >= POINTER_SIZE)
+         || TYPE_PRECISION (endtype)
+            >= int_or_pointer_precision (TREE_TYPE (value)))
        {
          tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
                                                      endtype);
@@ -4337,7 +4346,8 @@ initializer_constant_valid_p (tree value, tree endtype)
 
     case MINUS_EXPR:
       if (! INTEGRAL_TYPE_P (endtype)
-         || TYPE_PRECISION (endtype) >= POINTER_SIZE)
+         || TYPE_PRECISION (endtype)
+            >= int_or_pointer_precision (TREE_TYPE (value)))
        {
          tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
                                                      endtype);
@@ -4458,7 +4468,9 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
      resolving it.  */
   if (TREE_CODE (exp) == NOP_EXPR
       && POINTER_TYPE_P (TREE_TYPE (exp))
-      && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+      && targetm.addr_space.valid_pointer_mode
+          (TYPE_MODE (TREE_TYPE (exp)),
+           TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)))))
     {
       tree saved_type = TREE_TYPE (exp);
 
@@ -4466,7 +4478,9 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
         pointer modes.  */
       while (TREE_CODE (exp) == NOP_EXPR
             && POINTER_TYPE_P (TREE_TYPE (exp))
-            && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+            && targetm.addr_space.valid_pointer_mode
+                 (TYPE_MODE (TREE_TYPE (exp)),
+                  TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)))))
        exp = TREE_OPERAND (exp, 0);
 
       /* If what we're left with is the address of something, we can
@@ -6562,14 +6576,6 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   return local_p;
 }
 
-/* Determine whether or not a pointer mode is valid. Assume defaults
-   of ptr_mode or Pmode - can be overridden.  */
-bool
-default_valid_pointer_mode (enum machine_mode mode)
-{
-  return (mode == ptr_mode || mode == Pmode);
-}
-
 /* Default function to output code that will globalize a label.  A
    target must define GLOBAL_ASM_OP or provide its own function to
    globalize a label.  */