This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[named-addr-spaces-branch] More cleanup and fixes


Hello,

I've checked in some more updates to the named-addr-spaces-branch.
This is mostly cleanup (coding style, doc rewording, minor fixes),
but also includes a number of additional places I noticed where
conversions between pointers to different address spaces need to
be handled specially.

Tested on spu-elf and s390x-ibm-linux.

Bye,
Ulrich


ChangeLog:

	* doc/tm.texi (Named Address Spaces): Update documentation.
	* doc/invoke.texi (-mea64/-mea32): Reword.
	(-mcache-size=): Reword.
	(-matomic-updates/-mno-atomic-updates): Reword.

	* targhooks.c (default_addr_space_convert): Fix whitespace.
	* auto-inc-dec.c (try_merge): Likewise.
	* dse.c (replace_inc_dec): Likewise.
	* c-decl.c (grokdeclarator): Likewise.
	* explow.c (convert_memory_address_addr_space): Likewise.
	* tree-ssa-loop-ivopts.c (multiplier_allowed_in_address_p): Likewise.
	(get_address_cost): Fix merge issue.
	* tree-ssa-address.c (addr_for_mem_ref): Revert local change.
	* c-typeck.c (build_binary_op): Fix warning.
	* ifcvt.c (noce_try_cmove_arith): Handle named address spaces.

	* tree.h (MIXED_ADDR_SPACE_POINTER_TYPES_P): New macro.
	* tree.c (tree_nop_conversion): Use MIXED_ADDR_SPACE_POINTER_TYPES_P.
	* fold-const.c (fold_convert_const): Likewise.
	(operand_equal_p): Likewise).
	(fold_unary_loc): Likewise.
	* dojump.c (do_jump): Likewise.
	* tree-ssa-ifcombine (get_name_for_bit_test): Likewise.
	(recognize_single_bit_test): Likewise.
	* varasm.c (narrowing_initializer_constant_valid_p): Likewise.
	* tree-ssa.c (useless_type_conversion_p): Likewise.
	* tree-ssa-ccp.c (ccp_fold): Handle named address spaces.
	(fold_gimple_assign): Likewise.
	* gimplify.c (gimplify_conversion): Likewise.

	* expr.h (change_address_addr_space): Remove prototype.
	* emit-rtl.c (change_address_1): Remove address space argument.
	(change_address_addr_space): Remove.
	(adjust_address_1): Remove local change.
	(adjust_automodify_address_1): Likewise.
	(offset_address): Likewise.
	(replace_equiv_address): Likewise.

	* rtlanal.c: Include "targhooks.h".
	* simplify-rtx.c: Likewise.
	* Makefile.in (rtlanal.o, simplify-rtx.o): Update dependencies.

	* config/spu/spu-cache.h: Update to GPLv3.  Fix namespace violation.
	* config/spu/cachemgr.c: Update to GPLv3.  Fix formatting.
	(GET_TAG): Do not define variable in macro.
	(addr): Use typedef instead of macro.
	(si_from_eavoid): Remove.
	(GET_ENTRY): Avoid warning due to si_to_ptr use.
	(__cache_evict_entry): Update.
	(__cache_evict): Update.
	(__cache_miss): Update.
	(__cache_fetch_dirty): Update.  Avoid warning due to si_to_ptr use.
	(__cache_flush_stub): Remove.
	(__cache_flush): Mark as destructor.
	* config/spu/cache.S: Update to GPLv3.  Fix formatting.
	* config/spu/spu.opt: Add -mno-atomic-updates.
	* config/spu/spu.c (expand_ea_mem): Create new MEM RTX instead
	of calling change_address_addr_space.  Set alignment.


testsuite/ChangeLog:

	* gcc.target/spu/ea/ea.exp: Update copyright years.  Fix whitespace.



Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi	(revision 150857)
--- gcc/doc/tm.texi	(working copy)
*************** address spaces other than the default ad
*** 9813,9824 ****
  spaces are new keywords that are similar to the @code{volatile} and
  @code{const} type attributes.
  
! Named address pointers can be a different size than native pointers.
  
  For example, the SPU port uses the @code{__ea} address space to refer
  to memory in the host processor, rather than memory local to the SPU
  processor.  Access to memory in the @code{__ea} address space involves
! making calls to move the memory to/from the host processor to the
  local processor memory address space.  Pointers in the @code{__ea}
  address space are either 32 bits or 64 bits based on the
  @option{-mea32} or @option{-mea64} switches (native SPU pointers are
--- 9813,9825 ----
  spaces are new keywords that are similar to the @code{volatile} and
  @code{const} type attributes.
  
! Pointers to named address spaces can a a different size than
! pointers to the generic address space.
  
  For example, the SPU port uses the @code{__ea} address space to refer
  to memory in the host processor, rather than memory local to the SPU
  processor.  Access to memory in the @code{__ea} address space involves
! issuing DMA operations to move data between the host processor and the
  local processor memory address space.  Pointers in the @code{__ea}
  address space are either 32 bits or 64 bits based on the
  @option{-mea32} or @option{-mea64} switches (native SPU pointers are
*************** Define this to return true if @var{exp} 
*** 9869,9883 ****
  @var{mode} in the named address space @var{as}.  The @var{strict}
  parameter says whether strict addressing is in effect after reload has
  finished.  This target hook is the same as the
! @code{TARGET_LEGITIMATE_ADDRESS_P} target hook, except that includes
  explicit named address space support.
  @end deftypefn
  
  @deftypefn {Target Hook} {rtx} TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS (rtx @var{x}, rtx @var{oldx}, enum machine_mode @var{mode}, addr_space_t @var{as})
  Define this to modify an invalid address @var{x} to be a valid address
  with mode @var{mode} in the named address space @var{as}.  This target
! hook is the same as the @code{LEGITIMIZE_ADDRESS} target hook, except
! that it includes explicit named address space support.
  @end deftypefn
  
  @deftypefn {Target Hook} {bool} TARGET_ADDR_SPACE_SUBSET_P (addr_space_t @var{superset}, addr_space_t @var{subset})
--- 9870,9884 ----
  @var{mode} in the named address space @var{as}.  The @var{strict}
  parameter says whether strict addressing is in effect after reload has
  finished.  This target hook is the same as the
! @code{TARGET_LEGITIMATE_ADDRESS_P} target hook, except that it includes
  explicit named address space support.
  @end deftypefn
  
  @deftypefn {Target Hook} {rtx} TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS (rtx @var{x}, rtx @var{oldx}, enum machine_mode @var{mode}, addr_space_t @var{as})
  Define this to modify an invalid address @var{x} to be a valid address
  with mode @var{mode} in the named address space @var{as}.  This target
! hook is the same as the @code{TARGET_LEGITIMIZE_ADDRESS} target hook,
! except that it includes explicit named address space support.
  @end deftypefn
  
  @deftypefn {Target Hook} {bool} TARGET_ADDR_SPACE_SUBSET_P (addr_space_t @var{superset}, addr_space_t @var{subset})
*************** contained within the @var{superset} name
*** 9886,9892 ****
  a named address space that is a subset of another named address space
  will be converted automatically without a cast if used together in
  arithmetic operations.  Pointers to a superset address space can be
! converted to pointer to a subset address space via explict casts.
  @end deftypefn
  
  @deftypefn {Target Hook} {rtx} TARGET_ADDR_SPACE_CONVERT (rtx @var{op}, tree @var{from_type}, tree @var{to_type})
--- 9887,9893 ----
  a named address space that is a subset of another named address space
  will be converted automatically without a cast if used together in
  arithmetic operations.  Pointers to a superset address space can be
! converted to pointers to a subset address space via explict casts.
  @end deftypefn
  
  @deftypefn {Target Hook} {rtx} TARGET_ADDR_SPACE_CONVERT (rtx @var{op}, tree @var{from_type}, tree @var{to_type})
Index: gcc/doc/invoke.texi
===================================================================
*** gcc/doc/invoke.texi	(revision 150857)
--- gcc/doc/invoke.texi	(working copy)
*************** specified separated by a comma.
*** 15898,15908 ****
  @itemx -mea64
  @opindex mea32
  @opindex mea64
! Compile code assuming that pointers to the @code{__ea} address space are
! either 32 or 64 bits wide.  The default is 32 bits.  The @code{__ea}
! address space qualifier specifies that variables reside in the PPU
! address space.  As this is an ABI changing option, all object code in an
! executable must be compiled with the same option.
  
  @item -maddress-space-conversion
  @itemx -mno-address-space-conversion
--- 15898,15907 ----
  @itemx -mea64
  @opindex mea32
  @opindex mea64
! Compile code assuming that pointers to the PPU address space accessed
! via the @code{__ea} named address space qualifier are either 32 or 64
! bits wide.  The default is 32 bits.  As this is an ABI changing option,
! all object code in an executable must be compiled with the same setting.
  
  @item -maddress-space-conversion
  @itemx -mno-address-space-conversion
*************** Allow/disallow treating the @code{__ea} 
*** 15912,15926 ****
  of the generic address space.  This enables explicit type casts
  between @code{__ea} and generic pointer as well as implicit
  conversions of generic pointers to @code{__ea} pointers.  The
! default is to allow address space pointer conversions. 
  
  @item -mcache-size=@var{cache-size}
  @opindex mcache-size
  This option controls the version of libgcc that the compiler links to an
  executable and selects a software-managed cache for accessing variables
! in the PPU address space with a particular cache size.  Possible options
! for @var{cache-size} are @samp{8}, @samp{16}, @samp{32}, @samp{64} and
! @samp{128}.  The default cache size is 64KB.
  
  @item -matomic-updates
  @itemx -mno-atomic-updates
--- 15911,15925 ----
  of the generic address space.  This enables explicit type casts
  between @code{__ea} and generic pointer as well as implicit
  conversions of generic pointers to @code{__ea} pointers.  The
! default is to allow address space pointer conversions.
  
  @item -mcache-size=@var{cache-size}
  @opindex mcache-size
  This option controls the version of libgcc that the compiler links to an
  executable and selects a software-managed cache for accessing variables
! in the @code{__ea} address space with a particular cache size.  Possible
! options for @var{cache-size} are @samp{8}, @samp{16}, @samp{32}, @samp{64}
! and @samp{128}.  The default cache size is 64KB.
  
  @item -matomic-updates
  @itemx -mno-atomic-updates
*************** for @var{cache-size} are @samp{8}, @samp
*** 15928,15935 ****
  @opindex mno-atomic-updates
  This option controls the version of libgcc that the compiler links to an
  executable and selects whether atomic updates to the software-managed
! cache of PPU-side variables are used.  The default behavior is to use
! atomic updates.
  
  @item -mdual-nops
  @itemx -mdual-nops=@var{n}
--- 15927,15938 ----
  @opindex mno-atomic-updates
  This option controls the version of libgcc that the compiler links to an
  executable and selects whether atomic updates to the software-managed
! cache of PPU-side variables are used.  If you use atomic updates, changes
! to a PPU variable from SPU code using the @code{__ea} named address space
! qualifier will not interfere with changes to other PPU variables residing
! in the same cache line from PPU code.  If you do not use atomic updates,
! such interference may occur; however, writing back cache lines will be
! more efficient.  The default behavior is to use atomic updates.
  
  @item -mdual-nops
  @itemx -mdual-nops=@var{n}
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c	(revision 150857)
--- gcc/targhooks.c	(working copy)
*************** default_addr_space_subset_p (addr_space_
*** 848,854 ****
  /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be
     called for targets with only a generic address space.  */
  
! rtx 
  default_addr_space_convert (rtx op ATTRIBUTE_UNUSED,
  			    tree from_type ATTRIBUTE_UNUSED,
  			    tree to_type ATTRIBUTE_UNUSED)
--- 848,854 ----
  /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be
     called for targets with only a generic address space.  */
  
! rtx
  default_addr_space_convert (rtx op ATTRIBUTE_UNUSED,
  			    tree from_type ATTRIBUTE_UNUSED,
  			    tree to_type ATTRIBUTE_UNUSED)
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 150857)
--- gcc/tree.c	(working copy)
*************** tree_nop_conversion (const_tree exp)
*** 9754,9762 ****
    inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
  
    /* Keep conversions between pointers to different address spaces.  */
!   if (POINTER_TYPE_P (outer_type) && POINTER_TYPE_P (inner_type)
!       && TYPE_ADDR_SPACE (TREE_TYPE (outer_type))
! 	 != TYPE_ADDR_SPACE (TREE_TYPE (inner_type)))
      return false;
  
    /* Use precision rather then machine mode when we can, which gives
--- 9754,9760 ----
    inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
  
    /* Keep conversions between pointers to different address spaces.  */
!   if (MIXED_ADDR_SPACE_POINTER_TYPES_P (outer_type, inner_type))
      return false;
  
    /* Use precision rather then machine mode when we can, which gives
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 150857)
--- gcc/tree.h	(working copy)
*************** extern void omp_clause_range_check_faile
*** 1063,1068 ****
--- 1063,1076 ----
  #define POINTER_TYPE_P(TYPE) \
    (TREE_CODE (TYPE) == POINTER_TYPE || TREE_CODE (TYPE) == REFERENCE_TYPE)
  
+ /* Nonzero if TYPE1 and TYPE2 are two pointer or reference types
+    to different address spaces.  */
+ 
+ #define MIXED_ADDR_SPACE_POINTER_TYPES_P(TYPE1,TYPE2) \
+   (POINTER_TYPE_P (TYPE1) && POINTER_TYPE_P (TYPE2) \
+    && (TYPE_ADDR_SPACE (TREE_TYPE (TYPE1)) \
+        != TYPE_ADDR_SPACE (TREE_TYPE (TYPE2))))
+ 
  /* Nonzero if this type is a complete type.  */
  #define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
  
Index: gcc/rtlanal.c
===================================================================
*** gcc/rtlanal.c	(revision 150857)
--- gcc/rtlanal.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 38,43 ****
--- 38,44 ----
  #include "function.h"
  #include "df.h"
  #include "tree.h"
+ #include "targhooks.h"
  
  /* Forward declarations */
  static void set_of_1 (rtx, const_rtx, void *);
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 150857)
--- gcc/fold-const.c	(working copy)
*************** fold_convert_const (enum tree_code code,
*** 2463,2471 ****
  
    /* Conversions between non-NULL pointers to different
       address spaces must be preserved.  */
!   if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (arg1))
!       && TYPE_ADDR_SPACE (TREE_TYPE (type))
! 	 != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))
        && !integer_zerop (arg1))
      return NULL_TREE;
  
--- 2463,2469 ----
  
    /* Conversions between non-NULL pointers to different
       address spaces must be preserved.  */
!   if (MIXED_ADDR_SPACE_POINTER_TYPES_P (type, TREE_TYPE (arg1))
        && !integer_zerop (arg1))
      return NULL_TREE;
  
*************** operand_equal_p (const_tree arg0, const_
*** 3114,3119 ****
--- 3112,3121 ----
        || POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE (arg1)))
      return 0;
  
+   /* We cannot consider pointers to different address space equal.  */
+   if (MIXED_ADDR_SPACE_POINTER_TYPES_P (TREE_TYPE (arg0), TREE_TYPE (arg1)))
+     return 0;
+ 
    /* If both types don't have the same precision, then it is not safe
       to strip NOPs.  */
    if (TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION (TREE_TYPE (arg1)))
*************** fold_unary_loc (location_t loc, enum tre
*** 8449,8460 ****
  	      && ! (final_ptr && inside_prec != inter_prec)
  	      && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
  		    && TYPE_MODE (type) == TYPE_MODE (inter_type))
! 	      && ! (final_ptr && inter_ptr
! 		    && TYPE_ADDR_SPACE (TREE_TYPE (type))
! 		       != TYPE_ADDR_SPACE (TREE_TYPE (inter_type)))
! 	      && ! (inter_ptr && inside_ptr
! 		    && TYPE_ADDR_SPACE (TREE_TYPE (inter_type))
! 		       != TYPE_ADDR_SPACE (TREE_TYPE (inside_type))))
  	    return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0));
  	}
  
--- 8451,8458 ----
  	      && ! (final_ptr && inside_prec != inter_prec)
  	      && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
  		    && TYPE_MODE (type) == TYPE_MODE (inter_type))
! 	      && ! MIXED_ADDR_SPACE_POINTER_TYPES_P (inter_type, inside_type)
! 	      && ! MIXED_ADDR_SPACE_POINTER_TYPES_P (type, inter_type))
  	    return fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 0));
  	}
  
*************** fold_unary_loc (location_t loc, enum tre
*** 8640,8646 ****
  	  && (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
  	      || POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
  	  && (TYPE_PRECISION (TREE_TYPE (op0))
! 	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
  	return fold_build1_loc (loc, VIEW_CONVERT_EXPR,
  			    type, TREE_OPERAND (op0, 0));
  
--- 8638,8646 ----
  	  && (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
  	      || POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
  	  && (TYPE_PRECISION (TREE_TYPE (op0))
! 	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))))
! 	  && !MIXED_ADDR_SPACE_POINTER_TYPES_P
! 		(TREE_TYPE (op0), TREE_TYPE (TREE_OPERAND (op0, 0))))
  	return fold_build1_loc (loc, VIEW_CONVERT_EXPR,
  			    type, TREE_OPERAND (op0, 0));
  
Index: gcc/ChangeLog.named2
===================================================================
*** gcc/ChangeLog.named2	(revision 150857)
--- gcc/ChangeLog.named2	(working copy)
***************
*** 477,496 ****
  	    Michael Meissner  <meissner@linux.vnet.ibm.com>
  	    Ulrich Weigand  <uweigand@de.ibm.com>
  
! 	* testsuite/gcc.target/spu/ea/ea.exp: New file for named
  	address space support.
! 	* testsuite/gcc.target/spu/ea/cache1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/cast1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/cast2.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/compile1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/compile2.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/cppdefine.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/errors1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/errors2.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/execute1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/execute2.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/execute3.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/ops1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/ops2.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/options1.c: Ditto.
! 	* testsuite/gcc.target/spu/ea/test-sizes.c: Ditto.
--- 477,497 ----
  	    Michael Meissner  <meissner@linux.vnet.ibm.com>
  	    Ulrich Weigand  <uweigand@de.ibm.com>
  
! 	* gcc.target/spu/ea/ea.exp: New file for named
  	address space support.
! 	* gcc.target/spu/ea/cache1.c: Ditto.
! 	* gcc.target/spu/ea/cast1.c: Ditto.
! 	* gcc.target/spu/ea/cast2.c: Ditto.
! 	* gcc.target/spu/ea/compile1.c: Ditto.
! 	* gcc.target/spu/ea/compile2.c: Ditto.
! 	* gcc.target/spu/ea/cppdefine.c: Ditto.
! 	* gcc.target/spu/ea/errors1.c: Ditto.
! 	* gcc.target/spu/ea/errors2.c: Ditto.
! 	* gcc.target/spu/ea/execute1.c: Ditto.
! 	* gcc.target/spu/ea/execute2.c: Ditto.
! 	* gcc.target/spu/ea/execute3.c: Ditto.
! 	* gcc.target/spu/ea/ops1.c: Ditto.
! 	* gcc.target/spu/ea/ops2.c: Ditto.
! 	* gcc.target/spu/ea/options1.c: Ditto.
! 	* gcc.target/spu/ea/test-sizes.c: Ditto.
! 
Index: gcc/auto-inc-dec.c
===================================================================
*** gcc/auto-inc-dec.c	(revision 150857)
--- gcc/auto-inc-dec.c	(working copy)
*************** try_merge (void)
*** 693,699 ****
      case DISP_PRE:           /* ++con   */
        if (dump_file)
  	fprintf (dump_file, "trying DISP_PRE\n");
!       return attempt_change (gen_rtx_PRE_MODIFY (reg_mode, 
  						 inc_reg,
  						 gen_rtx_PLUS (reg_mode,
  							       inc_reg,
--- 693,699 ----
      case DISP_PRE:           /* ++con   */
        if (dump_file)
  	fprintf (dump_file, "trying DISP_PRE\n");
!       return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
  						 inc_reg,
  						 gen_rtx_PLUS (reg_mode,
  							       inc_reg,
*************** try_merge (void)
*** 715,721 ****
      case REG_PRE:            /* ++reg   */
        if (dump_file)
  	fprintf (dump_file, "trying PRE_REG\n");
!       return attempt_change (gen_rtx_PRE_MODIFY (reg_mode, 
  						 inc_reg,
  						 gen_rtx_PLUS (reg_mode,
  							       inc_reg,
--- 715,721 ----
      case REG_PRE:            /* ++reg   */
        if (dump_file)
  	fprintf (dump_file, "trying PRE_REG\n");
!       return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
  						 inc_reg,
  						 gen_rtx_PLUS (reg_mode,
  							       inc_reg,
*************** try_merge (void)
*** 726,732 ****
      case REG_POST:            /* reg++   */
        if (dump_file)
  	fprintf (dump_file, "trying POST_REG\n");
!       return attempt_change (gen_rtx_POST_MODIFY (reg_mode, 
  						  inc_reg,
  						  gen_rtx_PLUS (reg_mode,
  								inc_reg,
--- 726,732 ----
      case REG_POST:            /* reg++   */
        if (dump_file)
  	fprintf (dump_file, "trying POST_REG\n");
!       return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
  						  inc_reg,
  						  gen_rtx_PLUS (reg_mode,
  								inc_reg,
Index: gcc/testsuite/gcc.target/spu/ea/ea.exp
===================================================================
*** gcc/testsuite/gcc.target/spu/ea/ea.exp	(revision 150858)
--- gcc/testsuite/gcc.target/spu/ea/ea.exp	(working copy)
***************
*** 1,15 ****
! #   Copyright (C) 2008 Free Software Foundation, Inc.
  
  # This program is free software; you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation; either version 3 of the License, or
  # (at your option) any later version.
! # 
  # This program is distributed in the hope that it will be useful,
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  # GNU General Public License for more details.
! # 
  # You should have received a copy of the GNU General Public License
  # along with GCC; see the file COPYING3.  If not see
  # <http://www.gnu.org/licenses/>.
--- 1,15 ----
! #   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
  
  # This program is free software; you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation; either version 3 of the License, or
  # (at your option) any later version.
! #
  # This program is distributed in the hope that it will be useful,
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  # GNU General Public License for more details.
! #
  # You should have received a copy of the GNU General Public License
  # along with GCC; see the file COPYING3.  If not see
  # <http://www.gnu.org/licenses/>.
Index: gcc/testsuite/ChangeLog.named
===================================================================
*** gcc/testsuite/ChangeLog.named	(revision 150857)
--- gcc/testsuite/ChangeLog.named	(working copy)
***************
*** 1,3 ****
--- 1,37 ----
+ 2008-08-14  Ulrich Weigand  <uweigand@de.ibm.com>
+ 
+ 	* gcc.target/spu/ea/ea.exp (check_effective_target_ea64): Remove, ...
+ 	(check_effective_target_ea32): Remove, ...
+ 	(check_effective_target_ealib): ... and replace by this procedure.
+ 	Run all tests in both -mea32 and -mea64 mode.
+ 	Do not use global DEFAULT_CFLAGS.
+ 	* gcc.target/spu/ea/cache32.c: Remove, ...
+ 	* gcc.target/spu/ea/cache64.c: Remove, ...
+ 	* gcc.target/spu/ea/cache-common.h: Remove, ...
+ 	* gcc.target/spu/ea/cache1.c: ... and replace by this file.
+ 	* gcc.target/spu/ea/cppdefine32.c: Remove, ...
+ 	* gcc.target/spu/ea/cppdefine64.c: Remove, ...
+ 	* gcc.target/spu/ea/cppdefine.c: ... and replace by this file.
+ 	* gcc.target/spu/ea/test-sizes.c: Support both -mea32 and -mea64.
+ 	* gcc.target/spu/ea/errors.c: Rename to ...
+ 	* gcc.target/spu/ea/errors1.c: ... this.
+ 	* gcc.target/spu/ea/errors2.c: Remove.
+ 	* gcc.target/spu/ea/errors3.c: Remove.
+ 	* gcc.target/spu/ea/errors4.c: Rename to ...
+ 	* gcc.target/spu/ea/errors2.c: ... this.
+ 	* gcc.target/spu/ea/compile.c: Rename to ...
+ 	* gcc.target/spu/ea/compile1.c: ... this.
+ 	* gcc.target/spu/ea/compile2.c: Remove.
+ 	* gcc.target/spu/ea/compile3.c: Remove.
+ 	* gcc.target/spu/ea/compile4.c: Rename to ...
+ 	* gcc.target/spu/ea/compile2.c: ... this.
+ 	* gcc.target/spu/ea/execute1-m64.c: Remove.
+ 	* gcc.target/spu/ea/execute2-m64.c: Remove.
+ 	* gcc.target/spu/ea/execute3-m64.c: Remove.
+ 	* gcc.target/spu/ea/cast2.c: New test.
+ 	* gcc.target/spu/ea/ops1.c: New test.
+ 	* gcc.target/spu/ea/ops2.c: New test.
+ 
  2009-05-20  Michael Meissner  <meissner@linux.vnet.ibm.com>
  	    Ulrich Weigand  <uweigand@de.ibm.com>
  
***************
*** 190,195 ****
--- 224,237 ----
  
  	* gcc.target/spu/ea/ea.exp: Guard against non-SPU targets.
  
+ 2008-04-17  Ben Elliston  <bje@au.ibm.com>
+ 
+ 	* gcc.target/spu/cache.c: New test.
+ 
+ 2008-03-15  Ben Elliston  <bje@au.ibm.com>
+ 
+ 	* gcc.target/spu/ea/errors.c: Add a test case.
+ 
  2007-11-09  Ben Elliston  <bje@au.ibm.com>
  
  	* gcc.target/spu/ea/errors.c: Add int * __ea case.
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c	(revision 150857)
--- gcc/tree-ssa-ccp.c	(working copy)
*************** ccp_fold (gimple stmt)
*** 1043,1048 ****
--- 1043,1050 ----
  	      if (CONVERT_EXPR_CODE_P (subcode)
  		  && POINTER_TYPE_P (TREE_TYPE (lhs))
  		  && POINTER_TYPE_P (TREE_TYPE (op0))
+ 		  && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (lhs)))
+ 		      == TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0))))
  		  /* Do not allow differences in volatile qualification
  		     as this might get us confused as to whether a
  		     propagation destination statement is volatile
*************** fold_gimple_assign (gimple_stmt_iterator
*** 2799,2805 ****
  	  }
  	else if (CONVERT_EXPR_CODE_P (subcode)
  		 && POINTER_TYPE_P (gimple_expr_type (stmt))
! 		 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
  	  {
  	    tree type = gimple_expr_type (stmt);
  	    tree t = maybe_fold_offset_to_address (loc,
--- 2801,2810 ----
  	  }
  	else if (CONVERT_EXPR_CODE_P (subcode)
  		 && POINTER_TYPE_P (gimple_expr_type (stmt))
! 		 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))
! 		 && (TYPE_ADDR_SPACE (TREE_TYPE (gimple_expr_type (stmt)))
! 		     == TYPE_ADDR_SPACE
! 			 (TREE_TYPE (TREE_TYPE (gimple_assign_rhs1 (stmt))))))
  	  {
  	    tree type = gimple_expr_type (stmt);
  	    tree t = maybe_fold_offset_to_address (loc,
Index: gcc/dojump.c
===================================================================
*** gcc/dojump.c	(revision 150857)
--- gcc/dojump.c	(working copy)
*************** do_jump (tree exp, rtx if_false_label, r
*** 392,397 ****
--- 392,399 ----
  	  /* Strip narrowing integral type conversions.  */
  	  while (CONVERT_EXPR_P (exp0)
  		 && TREE_OPERAND (exp0, 0) != error_mark_node
+ 		 && !MIXED_ADDR_SPACE_POINTER_TYPES_P
+ 		       (TREE_TYPE (exp0), TREE_TYPE (TREE_OPERAND (exp0, 0)))
  		 && TYPE_PRECISION (TREE_TYPE (exp0))
  		    <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
  	    exp0 = TREE_OPERAND (exp0, 0);
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
*** gcc/tree-ssa-loop-ivopts.c	(revision 150857)
--- gcc/tree-ssa-loop-ivopts.c	(working copy)
*************** multiplier_allowed_in_address_p (HOST_WI
*** 3038,3044 ****
    unsigned int data_index = (int) as * MAX_MACHINE_MODE + (int) mode;
    static VEC (sbitmap, heap) *valid_mult_list;
    sbitmap valid_mult;
!  
    if (data_index >= VEC_length (sbitmap, valid_mult_list))
      VEC_safe_grow_cleared (sbitmap, heap, valid_mult_list, data_index + 1);
  
--- 3038,3044 ----
    unsigned int data_index = (int) as * MAX_MACHINE_MODE + (int) mode;
    static VEC (sbitmap, heap) *valid_mult_list;
    sbitmap valid_mult;
! 
    if (data_index >= VEC_length (sbitmap, valid_mult_list))
      VEC_safe_grow_cleared (sbitmap, heap, valid_mult_list, data_index + 1);
  
*************** get_address_cost (bool symbol_present, b
*** 3185,3206 ****
        if (HAVE_PRE_DECREMENT)
  	{
  	  addr = gen_rtx_PRE_DEC (address_mode, reg0);
! 	  has_predec[mem_mode] = memory_address_p (mem_mode, addr);
  	}
        if (HAVE_POST_DECREMENT)
  	{
  	  addr = gen_rtx_POST_DEC (address_mode, reg0);
! 	  has_postdec[mem_mode] = memory_address_p (mem_mode, addr);
  	}
        if (HAVE_PRE_INCREMENT)
  	{
  	  addr = gen_rtx_PRE_INC (address_mode, reg0);
! 	  has_preinc[mem_mode] = memory_address_p (mem_mode, addr);
  	}
        if (HAVE_POST_INCREMENT)
  	{
  	  addr = gen_rtx_POST_INC (address_mode, reg0);
! 	  has_postinc[mem_mode] = memory_address_p (mem_mode, addr);
  	}
        for (i = 0; i < 16; i++)
  	{
--- 3185,3210 ----
        if (HAVE_PRE_DECREMENT)
  	{
  	  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 (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 (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 (address_mode, reg0);
! 	  has_postinc[mem_mode]
! 	    = memory_address_addr_space_p (mem_mode, addr, as);
  	}
        for (i = 0; i < 16; i++)
  	{
Index: gcc/ChangeLog.named
===================================================================
*** gcc/ChangeLog.named	(revision 150857)
--- gcc/ChangeLog.named	(working copy)
***************
*** 320,357 ****
  	* config/spu/spu.md ("to_ea"): Remove.
  	("from_ea"): Likewise.
  
- 	* testsuite/spu/ea/ea.exp (check_effective_target_ea64): Remove, ...
- 	(check_effective_target_ea32): Remove, ...
- 	(check_effective_target_ealib): ... and replace by this procedure.
- 	Run all tests in both -mea32 and -mea64 mode.
- 	Do not use global DEFAULT_CFLAGS.
- 	* testsuite/spu/ea/cache32.c: Remove, ...
- 	* testsuite/spu/ea/cache64.c: Remove, ...
- 	* testsuite/spu/ea/cache-common.h: Remove, ...
- 	* testsuite/spu/ea/cache1.c: ... and replace by this file.
- 	* testsuite/spu/ea/cppdefine32.c: Remove, ...
- 	* testsuite/spu/ea/cppdefine64.c: Remove, ...
- 	* testsuite/spu/ea/cppdefine.c: ... and replace by this file.
- 	* testsuite/spu/ea/test-sizes.c: Support both -mea32 and -mea64.
- 	* testsuite/spu/ea/errors.c: Rename to ...
- 	* testsuite/spu/ea/errors1.c: ... this.
- 	* testsuite/spu/ea/errors2.c: Remove.
- 	* testsuite/spu/ea/errors3.c: Remove.
- 	* testsuite/spu/ea/errors4.c: Rename to ...
- 	* testsuite/spu/ea/errors2.c: ... this.
- 	* testsuite/spu/ea/compile.c: Rename to ...
- 	* testsuite/spu/ea/compile1.c: ... this.
- 	* testsuite/spu/ea/compile2.c: Remove.
- 	* testsuite/spu/ea/compile3.c: Remove.
- 	* testsuite/spu/ea/compile4.c: Rename to ...
- 	* testsuite/spu/ea/compile2.c: ... this.
- 	* testsuite/spu/ea/execute1-m64.c: Remove.
- 	* testsuite/spu/ea/execute2-m64.c: Remove.
- 	* testsuite/spu/ea/execute3-m64.c: Remove.
- 	* testsuite/spu/ea/cast2.c: New test.
- 	* testsuite/spu/ea/ops1.c: New test.
- 	* testsuite/spu/ea/ops2.c: New test.
- 
  2009-07-28  Ulrich Weigand  <uweigand@de.ibm.com>
  
  	Merge up to mainline revision 150048.
--- 320,325 ----
***************
*** 1628,1640 ****
  2008-04-17  Ben Elliston  <bje@au.ibm.com>
  
  	* config/spu/spu.c: Various bug fixes.
- 	* testsuite/gcc.target/spu/cache.c: New test.
  
  2008-03-15  Ben Elliston  <bje@au.ibm.com>
  
! 	* gcc/c-parser.c: Diagnose address space qualified compound
  	literals in function bodies.
- 	* gcc/testsuite/gcc.dg/ea/errors.c: Add a test case.
  
  2007-11-09  Ben Elliston  <bje@au.ibm.com>
  
--- 1596,1606 ----
  2008-04-17  Ben Elliston  <bje@au.ibm.com>
  
  	* config/spu/spu.c: Various bug fixes.
  
  2008-03-15  Ben Elliston  <bje@au.ibm.com>
  
! 	* c-parser.c: Diagnose address space qualified compound
  	literals in function bodies.
  
  2007-11-09  Ben Elliston  <bje@au.ibm.com>
  
Index: gcc/ifcvt.c
===================================================================
*** gcc/ifcvt.c	(revision 150857)
--- gcc/ifcvt.c	(working copy)
*************** noce_try_cmove_arith (struct noce_if_inf
*** 1485,1490 ****
--- 1485,1493 ----
        set_mem_align (tmp,
  		     MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));
  
+       gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b));
+       set_mem_addr_space (tmp, MEM_ADDR_SPACE (if_info->a));
+ 
        noce_emit_move_insn (if_info->x, tmp);
      }
    else if (target != x)
Index: gcc/expr.h
===================================================================
*** gcc/expr.h	(revision 150857)
--- gcc/expr.h	(working copy)
*************** extern rtx memory_address_addr_space (en
*** 646,656 ****
     NULL for ADDR means don't change the address.)  */
  extern rtx change_address (rtx, enum machine_mode, rtx);
  
- /* Like change_address, except we change the address space of the memory
-    returned.  */
- extern rtx change_address_addr_space (rtx, enum machine_mode, rtx,
- 				      addr_space_t);
- 
  /* Return a memory reference like MEMREF, but with its mode changed
     to MODE and its address offset by OFFSET bytes.  */
  #define adjust_address(MEMREF, MODE, OFFSET) \
--- 646,651 ----
Index: gcc/tree-ssa-address.c
===================================================================
*** gcc/tree-ssa-address.c	(revision 150857)
--- gcc/tree-ssa-address.c	(working copy)
*************** addr_for_mem_ref (struct mem_address *ad
*** 188,193 ****
--- 188,194 ----
  {
    enum machine_mode address_mode = targetm.addr_space.address_mode (as);
    rtx address, sym, bse, idx, st, off;
+   struct mem_addr_template *templ;
  
    if (addr->step && !integer_onep (addr->step))
      st = immed_double_const (TREE_INT_CST_LOW (addr->step),
*************** addr_for_mem_ref (struct mem_address *ad
*** 203,209 ****
  
    if (!really_expand)
      {
-       mem_addr_template *templ = NULL;
        unsigned int templ_index
  	= TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off);
  
--- 204,209 ----
Index: gcc/dse.c
===================================================================
*** gcc/dse.c	(revision 150857)
--- gcc/dse.c	(working copy)
*************** replace_inc_dec (rtx *r, void *d)
*** 827,833 ****
        {
  	rtx r1 = XEXP (x, 0);
  	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;
--- 827,833 ----
        {
  	rtx r1 = XEXP (x, 0);
  	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;
*************** replace_inc_dec (rtx *r, void *d)
*** 838,844 ****
        {
  	rtx r1 = XEXP (x, 0);
  	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;
--- 838,844 ----
        {
  	rtx r1 = XEXP (x, 0);
  	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;
Index: gcc/tree-ssa-ifcombine.c
===================================================================
*** gcc/tree-ssa-ifcombine.c	(revision 150857)
--- gcc/tree-ssa-ifcombine.c	(working copy)
*************** get_name_for_bit_test (tree candidate)
*** 151,157 ****
      {
        gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
        if (is_gimple_assign (def_stmt)
! 	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
  	{
  	  if (TYPE_PRECISION (TREE_TYPE (candidate))
  	      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
--- 151,160 ----
      {
        gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
        if (is_gimple_assign (def_stmt)
! 	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
! 	  && !MIXED_ADDR_SPACE_POINTER_TYPES_P
! 	        (TREE_TYPE (candidate),
! 		 TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
  	{
  	  if (TYPE_PRECISION (TREE_TYPE (candidate))
  	      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
*************** recognize_single_bit_test (gimple cond, 
*** 198,203 ****
--- 201,209 ----
  
        while (is_gimple_assign (stmt)
  	     && ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+ 		  && !MIXED_ADDR_SPACE_POINTER_TYPES_P
+ 		       (TREE_TYPE (gimple_assign_lhs (stmt)),
+ 			TREE_TYPE (gimple_assign_rhs1 (stmt)))
  		  && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
  		      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
  		 || gimple_assign_ssa_name_copy_p (stmt)))
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c	(revision 150857)
--- gcc/c-decl.c	(working copy)
*************** grokdeclarator (const struct c_declarato
*** 4952,4958 ****
  	       c_addr_space_name (as1),
  	       c_addr_space_name (as2));
      }
!   
    if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
      type = TYPE_MAIN_VARIANT (type);
    type_quals = ((constp ? TYPE_QUAL_CONST : 0)
--- 4952,4958 ----
  	       c_addr_space_name (as1),
  	       c_addr_space_name (as2));
      }
! 
    if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
      type = TYPE_MAIN_VARIANT (type);
    type_quals = ((constp ? TYPE_QUAL_CONST : 0)
Index: gcc/c-typeck.c
===================================================================
*** gcc/c-typeck.c	(revision 150857)
--- gcc/c-typeck.c	(working copy)
*************** build_binary_op (location_t location, en
*** 9387,9393 ****
  	  tree tt1 = TREE_TYPE (type1);
  	  addr_space_t as0 = TYPE_ADDR_SPACE (tt0);
  	  addr_space_t as1 = TYPE_ADDR_SPACE (tt1);
! 	  addr_space_t as_common;
  
  	  /* Anything compares with void *.  void * compares with anything.
  	     Otherwise, the targets must be compatible
--- 9387,9393 ----
  	  tree tt1 = TREE_TYPE (type1);
  	  addr_space_t as0 = TYPE_ADDR_SPACE (tt0);
  	  addr_space_t as1 = TYPE_ADDR_SPACE (tt1);
! 	  addr_space_t as_common = 0;
  
  	  /* Anything compares with void *.  void * compares with anything.
  	     Otherwise, the targets must be compatible
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 150857)
--- gcc/gimplify.c	(working copy)
*************** gimplify_conversion (tree *expr_p)
*** 1808,1813 ****
--- 1808,1815 ----
    if (CONVERT_EXPR_P (*expr_p)
        && POINTER_TYPE_P (TREE_TYPE (*expr_p))
        && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
+       && TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (*expr_p)))
+ 	 == TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
        && (tem = maybe_fold_offset_to_address
  	  (EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0),
  	   integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE)
Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c	(revision 150857)
--- gcc/emit-rtl.c	(working copy)
*************** static GTY ((if_marked ("ggc_marked_p"),
*** 180,186 ****
  #define first_label_num (crtl->emit.x_first_label_num)
  
  static rtx make_call_insn_raw (rtx);
! static rtx change_address_1 (rtx, enum machine_mode, rtx, int, addr_space_t);
  static void set_used_decls (tree);
  static void mark_label_nuses (rtx);
  static hashval_t const_int_htab_hash (const void *);
--- 180,186 ----
  #define first_label_num (crtl->emit.x_first_label_num)
  
  static rtx make_call_insn_raw (rtx);
! static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
  static void set_used_decls (tree);
  static void mark_label_nuses (rtx);
  static hashval_t const_int_htab_hash (const void *);
*************** set_mem_size (rtx mem, rtx size)
*** 1895,1906 ****
     attributes are not changed.  */
  
  static rtx
! change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate,
! 		  addr_space_t as)
  {
    rtx new_rtx;
  
    gcc_assert (MEM_P (memref));
    if (mode == VOIDmode)
      mode = GET_MODE (memref);
    if (addr == 0)
--- 1895,1907 ----
     attributes are not changed.  */
  
  static rtx
! change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
  {
+   addr_space_t as;
    rtx new_rtx;
  
    gcc_assert (MEM_P (memref));
+   as = MEM_ADDR_SPACE (memref);
    if (mode == VOIDmode)
      mode = GET_MODE (memref);
    if (addr == 0)
*************** change_address_1 (rtx memref, enum machi
*** 1922,1944 ****
  
    new_rtx = gen_rtx_MEM (mode, addr);
    MEM_COPY_ATTRIBUTES (new_rtx, memref);
- 
-   if (as != MEM_ADDR_SPACE (memref))
-     set_mem_addr_space (new_rtx, as);
- 
    return new_rtx;
  }
  
! /* Like change_address_1 with VALIDATE nonzero, and the address space set, but
!    we are not saying in what way we are changing MEMREF, so we only preserve
!    the alias set.  */
  
  rtx
! change_address_addr_space (rtx memref, enum machine_mode mode, rtx addr,
! 			   addr_space_t as)
  {
!   rtx new_rtx = change_address_1 (memref, mode, addr, 1, as);
!   rtx size;
    enum machine_mode mmode = GET_MODE (new_rtx);
    unsigned int align;
  
--- 1923,1938 ----
  
    new_rtx = gen_rtx_MEM (mode, addr);
    MEM_COPY_ATTRIBUTES (new_rtx, memref);
    return new_rtx;
  }
  
! /* Like change_address_1 with VALIDATE nonzero, but we are not saying in what
!    way we are changing MEMREF, so we only preserve the alias set.  */
  
  rtx
! change_address (rtx memref, enum machine_mode mode, rtx addr)
  {
!   rtx new_rtx = change_address_1 (memref, mode, addr, 1), size;
    enum machine_mode mmode = GET_MODE (new_rtx);
    unsigned int align;
  
*************** change_address_addr_space (rtx memref, e
*** 1952,1984 ****
  	  || (MEM_EXPR (memref) == NULL
  	      && MEM_OFFSET (memref) == NULL
  	      && MEM_SIZE (memref) == size
- 	      && MEM_ADDR_SPACE (memref) == as
  	      && MEM_ALIGN (memref) == align))
  	return new_rtx;
  
        new_rtx = gen_rtx_MEM (mmode, XEXP (memref, 0));
        MEM_COPY_ATTRIBUTES (new_rtx, memref);
- 
-       if (as != MEM_ADDR_SPACE (new_rtx))
- 	set_mem_addr_space (new_rtx, as);
      }
  
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, as, mmode);
  
    return new_rtx;
  }
  
- /* Like change_address_addr_space, except we don't change the named address
-    space.  */
- 
- rtx
- change_address (rtx memref, enum machine_mode mode, rtx addr)
- {
-   return change_address_addr_space (memref, mode, addr,
- 				    MEM_ADDR_SPACE (memref));
- }
- 
  /* Return a memory reference like MEMREF, but with its mode changed
     to MODE and its address offset by OFFSET bytes.  If VALIDATE is
     nonzero, the memory address is forced to be valid.
--- 1946,1965 ----
  	  || (MEM_EXPR (memref) == NULL
  	      && MEM_OFFSET (memref) == NULL
  	      && MEM_SIZE (memref) == size
  	      && MEM_ALIGN (memref) == align))
  	return new_rtx;
  
        new_rtx = gen_rtx_MEM (mmode, XEXP (memref, 0));
        MEM_COPY_ATTRIBUTES (new_rtx, memref);
      }
  
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align,
! 		     MEM_ADDR_SPACE (memref), mmode);
  
    return new_rtx;
  }
  
  /* Return a memory reference like MEMREF, but with its mode changed
     to MODE and its address offset by OFFSET bytes.  If VALIDATE is
     nonzero, the memory address is forced to be valid.
*************** adjust_address_1 (rtx memref, enum machi
*** 2032,2038 ****
  	addr = plus_constant (addr, offset);
      }
  
!   new_rtx = change_address_1 (memref, mode, addr, validate, as);
  
    /* If the address is a REG, change_address_1 rightfully returns memref,
       but this would destroy memref's MEM_ATTRS.  */
--- 2013,2019 ----
  	addr = plus_constant (addr, offset);
      }
  
!   new_rtx = change_address_1 (memref, mode, addr, validate);
  
    /* If the address is a REG, change_address_1 rightfully returns memref,
       but this would destroy memref's MEM_ATTRS.  */
*************** rtx
*** 2076,2083 ****
  adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
  			     HOST_WIDE_INT offset, int validate)
  {
!   memref = change_address_1 (memref, VOIDmode, addr, validate,
! 			     MEM_ADDR_SPACE (memref));
    return adjust_address_1 (memref, mode, offset, validate, 0);
  }
  
--- 2057,2063 ----
  adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
  			     HOST_WIDE_INT offset, int validate)
  {
!   memref = change_address_1 (memref, VOIDmode, addr, validate);
    return adjust_address_1 (memref, mode, offset, validate, 0);
  }
  
*************** offset_address (rtx memref, rtx offset, 
*** 2110,2117 ****
      }
  
    update_temp_slot_address (XEXP (memref, 0), new_rtx);
!   new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1,
! 			      MEM_ADDR_SPACE (memref));
  
    /* If there are no changes, just return the original memory reference.  */
    if (new_rtx == memref)
--- 2090,2096 ----
      }
  
    update_temp_slot_address (XEXP (memref, 0), new_rtx);
!   new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1);
  
    /* If there are no changes, just return the original memory reference.  */
    if (new_rtx == memref)
*************** replace_equiv_address (rtx memref, rtx a
*** 2137,2144 ****
    /* change_address_1 copies the memory attribute structure without change
       and that's exactly what we want here.  */
    update_temp_slot_address (XEXP (memref, 0), addr);
!   return change_address_1 (memref, VOIDmode, addr, 1,
! 			   MEM_ADDR_SPACE (memref));
  }
  
  /* Likewise, but the reference is not required to be valid.  */
--- 2116,2122 ----
    /* change_address_1 copies the memory attribute structure without change
       and that's exactly what we want here.  */
    update_temp_slot_address (XEXP (memref, 0), addr);
!   return change_address_1 (memref, VOIDmode, addr, 1);
  }
  
  /* Likewise, but the reference is not required to be valid.  */
*************** replace_equiv_address (rtx memref, rtx a
*** 2146,2152 ****
  rtx
  replace_equiv_address_nv (rtx memref, rtx addr)
  {
!   return change_address_1 (memref, VOIDmode, addr, 0, MEM_ADDR_SPACE (memref));
  }
  
  /* Return a memory reference like MEMREF, but with its mode widened to
--- 2124,2130 ----
  rtx
  replace_equiv_address_nv (rtx memref, rtx addr)
  {
!   return change_address_1 (memref, VOIDmode, addr, 0);
  }
  
  /* Return a memory reference like MEMREF, but with its mode widened to
Index: gcc/simplify-rtx.c
===================================================================
*** gcc/simplify-rtx.c	(revision 150857)
--- gcc/simplify-rtx.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 39,44 ****
--- 39,45 ----
  #include "output.h"
  #include "ggc.h"
  #include "target.h"
+ #include "targhooks.h"
  
  /* Simplification and canonicalization of RTL.  */
  
Index: gcc/explow.c
===================================================================
*** gcc/explow.c	(revision 150857)
--- gcc/explow.c	(working copy)
*************** break_out_memory_refs (rtx x)
*** 319,325 ****
     arithmetic insns can be used.  */
  
  rtx
! convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED, 
  				   rtx x, addr_space_t as ATTRIBUTE_UNUSED)
  {
  #ifndef POINTERS_EXTEND_UNSIGNED
--- 319,325 ----
     arithmetic insns can be used.  */
  
  rtx
! convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
  				   rtx x, addr_space_t as ATTRIBUTE_UNUSED)
  {
  #ifndef POINTERS_EXTEND_UNSIGNED
Index: gcc/varasm.c
===================================================================
*** gcc/varasm.c	(revision 150857)
--- gcc/varasm.c	(working copy)
*************** narrowing_initializer_constant_valid_p (
*** 4125,4134 ****
  	break;
  
        /* Keep conversions between pointers to different address spaces.  */
!       if (POINTER_TYPE_P (TREE_TYPE (op0))
! 	  && POINTER_TYPE_P (TREE_TYPE (inner))
! 	  && TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)))
! 	     != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (inner))))
  	break;
  
        op0 = inner;
--- 4125,4132 ----
  	break;
  
        /* Keep conversions between pointers to different address spaces.  */
!       if (MIXED_ADDR_SPACE_POINTER_TYPES_P (TREE_TYPE (op0),
! 					    TREE_TYPE (inner)))
  	break;
  
        op0 = inner;
*************** narrowing_initializer_constant_valid_p (
*** 4145,4154 ****
  	break;
  
        /* Keep conversions between pointers to different address spaces.  */
!       if (POINTER_TYPE_P (TREE_TYPE (op0))
! 	  && POINTER_TYPE_P (TREE_TYPE (inner))
! 	  && TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)))
! 	     != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (inner))))
  	break;
  
        op1 = inner;
--- 4143,4150 ----
  	break;
  
        /* Keep conversions between pointers to different address spaces.  */
!       if (MIXED_ADDR_SPACE_POINTER_TYPES_P (TREE_TYPE (op1),
! 					    TREE_TYPE (inner)))
  	break;
  
        op1 = inner;
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c	(revision 150857)
--- gcc/tree-ssa.c	(working copy)
*************** useless_type_conversion_p (tree outer_ty
*** 875,882 ****
        && POINTER_TYPE_P (outer_type))
      {
        /* Do not lose casts between pointers to different address spaces.  */
!       if (TYPE_ADDR_SPACE (TREE_TYPE (inner_type))
! 	  != TYPE_ADDR_SPACE (TREE_TYPE (outer_type)))
  	return false;
  
        /* If the outer type is (void *) or a pointer to an incomplete
--- 875,881 ----
        && POINTER_TYPE_P (outer_type))
      {
        /* Do not lose casts between pointers to different address spaces.  */
!       if (MIXED_ADDR_SPACE_POINTER_TYPES_P (inner_type, outer_type))
  	return false;
  
        /* If the outer type is (void *) or a pointer to an incomplete
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in	(revision 150857)
--- gcc/Makefile.in	(working copy)
*************** print-rtl.o : print-rtl.c $(CONFIG_H) $(
*** 2658,2664 ****
  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
     $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
     $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
!    $(DF_H)
  
  varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
--- 2658,2664 ----
  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
     $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
     $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
!    targhooks.h $(DF_H)
  
  varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
*************** jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) 
*** 2762,2768 ****
  simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h \
     $(RECOG_H) $(EXPR_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) \
!    $(TREE_H) $(TARGET_H)
  cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
     gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
--- 2762,2768 ----
  simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h \
     $(RECOG_H) $(EXPR_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) \
!    $(TREE_H) $(TARGET_H) targhooks.h
  cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
     gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
Index: gcc/config/spu/spu_cache.h
===================================================================
*** gcc/config/spu/spu_cache.h	(revision 150857)
--- gcc/config/spu/spu_cache.h	(working copy)
***************
*** 1,8 ****
! /* Copyright (C) 2008 Free Software Foundation, Inc.
  
     This file is free software; you can redistribute it and/or modify it under
     the terms of the GNU General Public License as published by the Free
!    Software Foundation; either version 2 of the License, or (at your option)
     any later version.
  
     This file is distributed in the hope that it will be useful, but WITHOUT
--- 1,8 ----
! /* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
  
     This file is free software; you can redistribute it and/or modify it under
     the terms of the GNU General Public License as published by the Free
!    Software Foundation; either version 3 of the License, or (at your option)
     any later version.
  
     This file is distributed in the hope that it will be useful, but WITHOUT
***************
*** 10,28 ****
     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     for more details.
  
!    You should have received a copy of the GNU General Public License
!    along with this file; see the file COPYING.  If not, write to the Free
!    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
!    02110-1301, USA.  */
! 
! /* As a special exception, if you include this header file into source files
!    compiled by GCC, this header file does not by itself cause  the resulting
!    executable to be covered by the GNU General Public License.  This exception
!    does not however invalidate any other reasons why the executable file might be
!    covered by the GNU General Public License.  */
  
! #ifndef SPU_CACHEH
! #define SPU_CACHEH
  
  void *__cache_fetch_dirty (__ea void *ea, int n_bytes_dirty);
  void *__cache_fetch (__ea void *ea);
--- 10,26 ----
     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     for more details.
  
!    Under Section 7 of GPL version 3, you are granted additional
!    permissions described in the GCC Runtime Library Exception, version
!    3.1, as published by the Free Software Foundation.
! 
!    You should have received a copy of the GNU General Public License and
!    a copy of the GCC Runtime Library Exception along with this program;
!    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
!    <http://www.gnu.org/licenses/>.  */
  
! #ifndef _SPU_CACHE_H
! #define _SPU_CACHE_H
  
  void *__cache_fetch_dirty (__ea void *ea, int n_bytes_dirty);
  void *__cache_fetch (__ea void *ea);
Index: gcc/config/spu/cachemgr.c
===================================================================
*** gcc/config/spu/cachemgr.c	(revision 150857)
--- gcc/config/spu/cachemgr.c	(working copy)
***************
*** 1,30 ****
! /* Copyright (C) 2008  Free Software Foundation, Inc.
  
  This file is part of GCC.
  
  GCC is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
! Software Foundation; either version 2, or (at your option) any later
  version.
  
- In addition to the permissions in the GNU General Public License, the
- Free Software Foundation gives you unlimited permission to link the
- compiled version of this file into combinations with other programs,
- and to distribute those combinations without any restriction coming
- from the use of this file.  (The General Public License restrictions
- do apply in other respects; for example, they cover modification of
- the file, and distribution when not linked into a combine
- executable.)
- 
  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
! You should have received a copy of the GNU General Public License
! along with GCC; see the file COPYING.  If not, write to the Free
! Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
! 02110-1301, USA.  */
  
  #include <spu_mfcio.h>
  #include <spu_internals.h>
--- 1,25 ----
! /* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
  
  This file is part of GCC.
  
  GCC is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
! Software Foundation; either version 3, or (at your option) any later
  version.
  
  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
! 
! You should have received a copy of the GNU General Public License and
! a copy of the GCC Runtime Library Exception along with this program;
! see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
! <http://www.gnu.org/licenses/>.  */
  
  #include <spu_mfcio.h>
  #include <spu_internals.h>
*************** extern char __cache_tag_array_size;
*** 40,47 ****
  #define WAYS 4
  #define SET_MASK ((int) &__cache_tag_array_size - LINE_SIZE)
  
! #define CACHE_LINES ((int) &__cache_tag_array_size / \
!   sizeof (struct __cache_tag_array) * WAYS)
  
  struct __cache_tag_array
  {
--- 35,42 ----
  #define WAYS 4
  #define SET_MASK ((int) &__cache_tag_array_size - LINE_SIZE)
  
! #define CACHE_LINES ((int) &__cache_tag_array_size /		\
! 		     sizeof (struct __cache_tag_array) * WAYS)
  
  struct __cache_tag_array
  {
*************** extern struct __cache_tag_array __cache_
*** 56,125 ****
  extern char __cache[];
  
  /* In order to make the code seem a little cleaner, and to avoid having
!    64/32 bit ifdefs all over the place, we macro.  */
! 
! /* It may seem poor taste to define variables within a macro, but
!    it's C99 compliant.  */
  
  #ifdef __EA64__
! #define CHECK_TAG(_entry, _way, _tag) ((_entry->tag_lo[_way] == \
!   (_tag & 0xFFFFFFFF))&&(_entry->tag_hi[_way] == (_tag >> 32)))
  
! #define GET_TAG(_entry, _way) unsigned long long tag = _entry->tag_hi[_way]; \
!   tag = tag << 32;                                                           \
!   tag |= (_entry->tag_lo[_way]);
! 
! #define SET_TAG(_entry, _way, _tag)             \
!   _entry->tag_lo[_way] = (_tag & 0xFFFFFFFF);   \
!   _entry->tag_hi[_way] = (_tag >> 32);
  
- #define addr unsigned long long
- #define si_from_eavoid(_x) si_from_ullong (eavoid_to_eanum(_x))
  #else /*__EA32__*/
! #define CHECK_TAG(_entry, _way, _tag) (_entry->tag_lo[_way] == _tag)
  
! #define GET_TAG(_entry, _way) unsigned long tag = _entry->tag_lo[_way]
  
! #define SET_TAG(_entry, _way, _tag)     \
!   _entry->tag_lo[_way] = _tag;
  
- #define addr unsigned long
- #define si_from_eavoid(_x) si_from_uint (eavoid_to_eanum(_x))
  #endif
  
  /* In GET_ENTRY, we cast away the high 32 bits,
     as the tag is only in the low 32.  */
  
! #define GET_ENTRY(_addr) ((struct __cache_tag_array *)                  \
!         si_to_ptr(si_a                                                  \
!                    (si_and(si_from_uint((unsigned int) (addr) _addr),   \
!                            si_from_uint(SET_MASK)),                     \
!                     si_from_uint((unsigned int) __cache_tag_array))));
! 
! #define GET_CACHE_LINE(_addr, _way)  ((void *) (__cache +       \
!   (_addr & SET_MASK) * WAYS) + (_way * LINE_SIZE));
! 
! #define eavoid_to_eanum(_ea) ((addr) _ea)
! 
! #define CHECK_DIRTY(_vec) (si_to_uint (si_orx ((qword) _vec)))
! #define SET_EMPTY(_entry, _way) (_entry->tag_lo[_way] = 1)
! #define CHECK_EMPTY(_entry, _way) (_entry->tag_lo[_way] == 1)
  
  #define LS_FLAG 0x80000000
! #define SET_IS_LS(_entry, _way) (_entry->reserved[_way] |= LS_FLAG)
! #define CHECK_IS_LS(_entry, _way) (_entry->reserved[_way] & LS_FLAG)
! #define GET_LRU(_entry, _way) (_entry->reserved[_way] & ~(LS_FLAG))
  
- static void __cache_flush_stub (void) __attribute__ ((destructor));
  static int dma_tag = 32;
  
  static void
  __cache_evict_entry (struct __cache_tag_array *entry, int way)
  {
  
!   GET_TAG (entry, way);
! 
!   if ((CHECK_DIRTY (entry->dirty_bits[way])) && (!CHECK_IS_LS (entry, way)))
      {
  #ifdef NONATOMIC
        /* Non-atomic writes.  */
--- 51,116 ----
  extern char __cache[];
  
  /* In order to make the code seem a little cleaner, and to avoid having
!    64/32 bit ifdefs all over the place, we use macros.  */
  
  #ifdef __EA64__
! typedef unsigned long long addr;
  
! #define CHECK_TAG(_entry, _way, _tag)			\
!   ((_entry)->tag_lo[(_way)] == ((_tag) & 0xFFFFFFFF)	\
!    && (_entry)->tag_hi[(_way)] == ((_tag) >> 32))
! 
! #define GET_TAG(_entry, _way) \
!   ((unsigned long long)(_entry)->tag_hi[(_way)] << 32	\
!    | (unsigned long long)(_entry)->tag_lo[(_way)])
! 
! #define SET_TAG(_entry, _way, _tag)			\
!   (_entry)->tag_lo[(_way)] = (_tag) & 0xFFFFFFFF;	\
!   (_entry)->tag_hi[(_way)] = (_tag) >> 32
  
  #else /*__EA32__*/
! typedef unsigned long addr;
! 
! #define CHECK_TAG(_entry, _way, _tag)			\
!   ((_entry)->tag_lo[(_way)] == (_tag))
  
! #define GET_TAG(_entry, _way)				\
!   ((_entry)->tag_lo[(_way)])
  
! #define SET_TAG(_entry, _way, _tag)			\
!   (_entry)->tag_lo[(_way)] = (_tag)
  
  #endif
  
  /* In GET_ENTRY, we cast away the high 32 bits,
     as the tag is only in the low 32.  */
  
! #define GET_ENTRY(_addr)						   \
!   ((struct __cache_tag_array *)						   \
!    si_to_uint (si_a (si_and (si_from_uint ((unsigned int) (addr) (_addr)), \
! 			     si_from_uint (SET_MASK)),			   \
! 	       si_from_uint ((unsigned int) __cache_tag_array))))
! 
! #define GET_CACHE_LINE(_addr, _way) \
!   ((void *) (__cache + ((_addr) & SET_MASK) * WAYS) + ((_way) * LINE_SIZE));
! 
! #define CHECK_DIRTY(_vec) (si_to_uint (si_orx ((qword) (_vec))))
! #define SET_EMPTY(_entry, _way) ((_entry)->tag_lo[(_way)] = 1)
! #define CHECK_EMPTY(_entry, _way) ((_entry)->tag_lo[(_way)] == 1)
  
  #define LS_FLAG 0x80000000
! #define SET_IS_LS(_entry, _way) ((_entry)->reserved[(_way)] |= LS_FLAG)
! #define CHECK_IS_LS(_entry, _way) ((_entry)->reserved[(_way)] & LS_FLAG)
! #define GET_LRU(_entry, _way) ((_entry)->reserved[(_way)] & ~LS_FLAG)
  
  static int dma_tag = 32;
  
  static void
  __cache_evict_entry (struct __cache_tag_array *entry, int way)
  {
+   addr tag = GET_TAG (entry, way);
  
!   if (CHECK_DIRTY (entry->dirty_bits[way]) && !CHECK_IS_LS (entry, way))
      {
  #ifdef NONATOMIC
        /* Non-atomic writes.  */
*************** __cache_evict_entry (struct __cache_tag_
*** 215,234 ****
  void
  __cache_evict (__ea void *ea)
  {
!   addr tag = (eavoid_to_eanum (ea) & ~(TAG_MASK));
    struct __cache_tag_array *entry = GET_ENTRY (ea);
    int i = 0;
  
    /* Cycles through all the possible ways an address could be at
!      and evicts the way if found */
  
    for (i = 0; i < WAYS; i++)
!     {
!       if (CHECK_TAG (entry, i, tag))
! 	{
! 	  __cache_evict_entry (entry, i);
! 	}
!     }
  }
  
  static void *
--- 206,221 ----
  void
  __cache_evict (__ea void *ea)
  {
!   addr tag = (addr) ea & ~TAG_MASK;
    struct __cache_tag_array *entry = GET_ENTRY (ea);
    int i = 0;
  
    /* Cycles through all the possible ways an address could be at
!      and evicts the way if found.  */
  
    for (i = 0; i < WAYS; i++)
!     if (CHECK_TAG (entry, i, tag))
!       __cache_evict_entry (entry, i);
  }
  
  static void *
*************** static void
*** 266,272 ****
  __cache_miss (__ea void *ea, struct __cache_tag_array *entry, int way)
  {
  
!   addr tag = (eavoid_to_eanum (ea) & ~(TAG_MASK));
    unsigned int lru = 0;
    int i = 0;
    int idx = 0;
--- 253,259 ----
  __cache_miss (__ea void *ea, struct __cache_tag_array *entry, int way)
  {
  
!   addr tag = (addr) ea & ~TAG_MASK;
    unsigned int lru = 0;
    int i = 0;
    int idx = 0;
*************** __cache_miss (__ea void *ea, struct __ca
*** 298,310 ****
    /* Because the LS is not 256k aligned, we can't do a nice and mask
       here to compare, so we must check the whole range.  */
  
!   if ((eavoid_to_eanum (ea) >= (addr) __ea_local_store) &&
!       (eavoid_to_eanum (ea) < (addr) (__ea_local_store + 0x40000)))
      {
        SET_IS_LS (entry, way);
        entry->base[way] =
! 	(void *) ((unsigned int) (eavoid_to_eanum (ea) -
! 				  (addr) __ea_local_store) & ~(0x7f));
      }
    else
      {
--- 285,297 ----
    /* Because the LS is not 256k aligned, we can't do a nice and mask
       here to compare, so we must check the whole range.  */
  
!   if ((addr) ea >= (addr) __ea_local_store
!       && (addr) ea < (addr) (__ea_local_store + 0x40000))
      {
        SET_IS_LS (entry, way);
        entry->base[way] =
! 	(void *) ((unsigned int) ((addr) ea -
! 				  (addr) __ea_local_store) & ~0x7f);
      }
    else
      {
*************** __cache_fetch_dirty (__ea void *ea, int 
*** 335,352 ****
    tag_lo =
      si_to_uint (si_andc
  		(si_shufb
! 		 (si_from_eavoid (ea), si_from_uint (0),
  		  si_from_uint (0x00010203)), si_from_uint (TAG_MASK)));
  #else
    tag_lo =
      si_to_uint (si_andc
  		(si_shufb
! 		 (si_from_eavoid (ea), si_from_uint (0),
  		  si_from_uint (0x04050607)), si_from_uint (TAG_MASK)));
  
    tag_hi =
      si_to_uint (si_shufb
! 		(si_from_eavoid (ea), si_from_uint (0),
  		 si_from_uint (0x00010203)));
  #endif
  
--- 322,339 ----
    tag_lo =
      si_to_uint (si_andc
  		(si_shufb
! 		 (si_from_uint ((addr) ea), si_from_uint (0),
  		  si_from_uint (0x00010203)), si_from_uint (TAG_MASK)));
  #else
    tag_lo =
      si_to_uint (si_andc
  		(si_shufb
! 		 (si_from_ullong ((addr) ea), si_from_uint (0),
  		  si_from_uint (0x04050607)), si_from_uint (TAG_MASK)));
  
    tag_hi =
      si_to_uint (si_shufb
! 		(si_from_ullong ((addr) ea), si_from_uint (0),
  		 si_from_uint (0x00010203)));
  #endif
  
*************** missreturn:
*** 359,365 ****
    etag_lo = si_lqd (si_from_ptr (entry), 0);
    equal = si_ceq (etag_lo, si_from_uint (tag_lo));
  #ifdef __EA64__
!   /* And the high tag too  */
    etag_hi = si_lqd (si_from_ptr (entry), 16);
    equal = si_and (equal, (si_ceq (etag_hi, si_from_uint (tag_hi))));
  #endif
--- 346,352 ----
    etag_lo = si_lqd (si_from_ptr (entry), 0);
    equal = si_ceq (etag_lo, si_from_uint (tag_lo));
  #ifdef __EA64__
!   /* And the high tag too.  */
    etag_hi = si_lqd (si_from_ptr (entry), 16);
    equal = si_and (equal, (si_ceq (etag_hi, si_from_uint (tag_hi))));
  #endif
*************** missreturn:
*** 387,397 ****
        /* Rotate it around to the correct offset.  */
        bit_mask =
  	si_rotqby (bit_mask,
! 		   si_from_uint (-1 * (eavoid_to_eanum (ea) & TAG_MASK) / 8));
  
        bit_mask =
  	si_rotqbi (bit_mask,
! 		   si_from_uint (-1 * (eavoid_to_eanum (ea) & TAG_MASK) % 8));
  
        /* Update the dirty bits.  */
        si_stqx (si_or (si_lqx (si_from_ptr (entry), way), bit_mask),
--- 374,384 ----
        /* Rotate it around to the correct offset.  */
        bit_mask =
  	si_rotqby (bit_mask,
! 		   si_from_uint (-1 * ((addr) ea & TAG_MASK) / 8));
  
        bit_mask =
  	si_rotqbi (bit_mask,
! 		   si_from_uint (-1 * ((addr) ea & TAG_MASK) % 8));
  
        /* Update the dirty bits.  */
        si_stqx (si_or (si_lqx (si_from_ptr (entry), way), bit_mask),
*************** missreturn:
*** 399,405 ****
      };
  
    /* We've definitely found the right entry, set LRU (reserved) to 0
!      maintaining the LS flag (MSB). */
  
    si_stqd (si_andc
  	   (si_lqd (si_from_ptr (entry), 48),
--- 386,392 ----
      };
  
    /* We've definitely found the right entry, set LRU (reserved) to 0
!      maintaining the LS flag (MSB).  */
  
    si_stqd (si_andc
  	   (si_lqd (si_from_ptr (entry), 48),
*************** missreturn:
*** 407,416 ****
  	   si_from_ptr (entry), 48);
  
    return (void *)
!     si_to_ptr (si_a
! 	       (si_orx
! 		(si_and (si_lqd (si_from_ptr (entry), 32), equal)),
! 		si_from_uint (((unsigned int) (addr) ea) & TAG_MASK)));
  
  misshandler:
    equal = si_ceqi (etag_lo, 1);
--- 394,403 ----
  	   si_from_ptr (entry), 48);
  
    return (void *)
!     si_to_uint (si_a
! 		(si_orx
! 		 (si_and (si_lqd (si_from_ptr (entry), 32), equal)),
! 		 si_from_uint (((unsigned int) (addr) ea) & TAG_MASK)));
  
  misshandler:
    equal = si_ceqi (etag_lo, 1);
*************** __cache_touch (__ea void *ea __attribute
*** 430,459 ****
    /* NO-OP for now.  */
  }
  
! static void
! __cache_flush_stub (void)
! {
!   __cache_flush ();
! }
! 
  void
  __cache_flush (void)
  {
    struct __cache_tag_array *entry = __cache_tag_array;
!   unsigned int i = 0;
!   int j = 0;
  
    /* Cycle through each cache entry and evict all used ways.  */
  
!   for (i = 0; i < (CACHE_LINES / WAYS); i++)
      {
        for (j = 0; j < WAYS; j++)
! 	{
! 	  if (!CHECK_EMPTY (entry, j))
! 	    {
! 	      __cache_evict_entry (entry, j);
! 	    }
! 	}
        entry++;
      }
  }
--- 417,438 ----
    /* NO-OP for now.  */
  }
  
! void __cache_flush (void) __attribute__ ((destructor));
  void
  __cache_flush (void)
  {
    struct __cache_tag_array *entry = __cache_tag_array;
!   unsigned int i;
!   int j;
  
    /* Cycle through each cache entry and evict all used ways.  */
  
!   for (i = 0; i < CACHE_LINES / WAYS; i++)
      {
        for (j = 0; j < WAYS; j++)
! 	if (!CHECK_EMPTY (entry, j))
! 	  __cache_evict_entry (entry, j);
! 
        entry++;
      }
  }
Index: gcc/config/spu/cache.S
===================================================================
*** gcc/config/spu/cache.S	(revision 150857)
--- gcc/config/spu/cache.S	(working copy)
***************
*** 1,47 ****
! /* Copyright (C) 2008  Free Software Foundation, Inc.
  
  This file is part of GCC.
  
  GCC is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
! Software Foundation; either version 2, or (at your option) any later
  version.
  
- In addition to the permissions in the GNU General Public License, the
- Free Software Foundation gives you unlimited permission to link the
- compiled version of this file into combinations with other programs,
- and to distribute those combinations without any restriction coming
- from the use of this file.  (The General Public License restrictions
- do apply in other respects; for example, they cover modification of
- the file, and distribution when not linked into a combine
- executable.)
- 
  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
! You should have received a copy of the GNU General Public License
! along with GCC; see the file COPYING.  If not, write to the Free
! Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
! 02110-1301, USA.  */
! 
! .data
! .p2align 7
! .global __cache
  __cache:
! .rept __CACHE_SIZE__ * 8
! .fill 128
! .endr
  
! .p2align 7
! .global __cache_tag_array
  __cache_tag_array:
! .rept __CACHE_SIZE__ * 2
! .long 1, 1, 1, 1
! .fill 128-16
! .endr
  __end_cache_tag_array:
  
! .globl __cache_tag_array_size
! .set __cache_tag_array_size, __end_cache_tag_array-__cache_tag_array
--- 1,43 ----
! /* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
  
  This file is part of GCC.
  
  GCC is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
! Software Foundation; either version 3, or (at your option) any later
  version.
  
  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
! Under Section 7 of GPL version 3, you are granted additional
! permissions described in the GCC Runtime Library Exception, version
! 3.1, as published by the Free Software Foundation.
! 
! You should have received a copy of the GNU General Public License and
! a copy of the GCC Runtime Library Exception along with this program;
! see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
! <http://www.gnu.org/licenses/>.  */
! 
! 	.data
! 	.p2align 7
! 	.global __cache
  __cache:
! 	.rept __CACHE_SIZE__ * 8
! 	.fill 128
! 	.endr
  
! 	.p2align 7
! 	.global __cache_tag_array
  __cache_tag_array:
! 	.rept __CACHE_SIZE__ * 2
! 	.long 1, 1, 1, 1
! 	.fill 128-16
! 	.endr
  __end_cache_tag_array:
  
! 	.globl __cache_tag_array_size
! 	.set __cache_tag_array_size, __end_cache_tag_array-__cache_tag_array
! 
Index: gcc/config/spu/spu.opt
===================================================================
*** gcc/config/spu/spu.opt	(revision 150857)
--- gcc/config/spu/spu.opt	(working copy)
*************** matomic-updates
*** 107,109 ****
--- 107,113 ----
  Target Report
  Atomically write back software data cache lines (default)
  
+ mno-atomic-updates
+ Target Report
+ Do not atomically write back software data cache lines
+ 
Index: gcc/config/spu/spu.c
===================================================================
*** gcc/config/spu/spu.c	(revision 150857)
--- gcc/config/spu/spu.c	(working copy)
*************** expand_ea_mem (rtx mem, bool is_store)
*** 4554,4570 ****
    if (ea_alias_set == -1)
      ea_alias_set = new_alias_set ();
  
!   new_mem = change_address_addr_space (mem, VOIDmode, data_addr,
! 				       ADDR_SPACE_GENERIC);
! 
!   /* We can't just change the alias set directly to ea_alias_set, because the
!      --enable-checking code may complain that the alias sets don't conflict */
!   set_mem_alias_set (new_mem, 0);
    set_mem_alias_set (new_mem, ea_alias_set);
! 
!   /* Manually reset the address space of the pointer back to the generic
!      address space.  */
!   set_mem_addr_space (new_mem, ADDR_SPACE_GENERIC);
  
    return new_mem;
  }
--- 4554,4566 ----
    if (ea_alias_set == -1)
      ea_alias_set = new_alias_set ();
  
!   /* We generate a new MEM RTX to refer to the copy of the data
!      in the cache.  We do not copy memory attributes (except the
!      alignment) from the original MEM, as they may no longer apply
!      to the cache copy.  */
!   new_mem = gen_rtx_MEM (GET_MODE (mem), data_addr);
    set_mem_alias_set (new_mem, ea_alias_set);
!   set_mem_align (new_mem, MIN (MEM_ALIGN (mem), 128 * 8));
  
    return new_mem;
  }
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]