*revised* PATCH: named address space support (1/2: target-independent parts)

Ben Elliston bje@au1.ibm.com
Sat Aug 30 13:05:00 GMT 2008


Hi Joseph

Here is a revised patch.  I have MIME attached the SPU-specific
testcases (but would be committed separately with the SPU backend
changes).

Boostrapped on x86_64-linux and powerpc64-linux and regression tested on
spu-elf.  OK for the trunk? 

Cheers, Ben


2008-08-28  Ben Elliston  <bje@au.ibm.com>

	* c-decl.c: Include targhooks.h.
	(shadow_tag_warned): Include declspecs->address_space.
	(quals_from_declspecs): Encode address space number into quals.
	(grokdeclarator): Warn about duplicate address space qualifiers.
	Issue various diagnostics as specified by N1275.
	(build_null_declspecs): Clear ret->address_space.
	(declspecs_add_addrspace): New function.
	* c-objc-common.c (c_types_compatible_p): Two types in different
	address spaces are not compatible.
	* convert.c: Include target.h.
	(convert_to_pointer): Use targetm.addr_space_pointer_mode to
	calculate the width of a pointer.
	(convert_to_integer): Likewise.
	* c-parser.c (enum c_id_kind): Add C_ID_ADDRSPACE.
	(c_lex_one_token): Set token->id_kind to C_ID_ADDRSPACE if the
	token is a recognised address space.
	(c_token_starts_typename): Return true for C_ID_ADDRSPACE.
	(c_token_starts_declspecs): Likewise.
	(c_parser_declspecs): Handle C_ID_ADDRSPACE.
	(c_parser_postfix_expression_after_paren_type): Reject compound
	literals qualified by an address space qualifier.	
	* c-pretty-print.c: Include target.h and target-def.h.
	(pp_c_type_qualifier_list): Print address space if non-zero.
	* c-tree.h (struct c_declspecs): Add address_space field.
	(declspecs_add_addrspace): Prototype.
	* c-typeck.c (comptypes_internal): Use CONST_CAST_TREE.
	(build_binary_op): If an operand is a pointer into another address
	space, make the result of the comparison such a pointer also.
	* dwarf2out.c (modified_type_die): Set the DW_AT_address_class
	attribute to the address space number for pointer and reference
	types, if the type is in a non-generic address space.
	* emit-rtl.c (get_mem_attrs): Add address space parameter.
	(set_mem_attributes_minus_bitpos, set_mem_attrs_from_reg,
	set_mem_alias_set, set_mem_align, set_mem_expr, set_mem_offset,
	set_mem_size, change_address, adjust_address_1, offset_address,
	widen_memory_access): Update all callers.
	(set_mem_addr_space): New function.
	* emit-rtl.h (set_mem_addr_space): Declare.
	* explow.c (memory_address): Only convert memory addresses to
	Pmode if they are not valid pointer modes.
	* expr.c (expand_expr_addr_expr): Do not assume the target mode is
	Pmode.
	(expand_expr_real_1): Handle casts of pointers to/from non-generic
	address spaces.
	* fold-const.c: Include "target.h".
	(fit_double_type): Do not assume the type precision of a pointer
	is POINTER_SIZE.
	(fold_convert_const): Return NULL_TREE for non-generic pointers.
	* langhooks.c (lhd_tree_dump_type_quals): Use CONST_CAST_TREE.
	* output.h (default_addr_space_pointer_mode): Declare.
	* print-rtl.c (print_rtx): Output the address space number, if
	non-zero.
	* rtl.h (struct mem_attrs): Add addrspace field.
	(MEM_ADDR_SPACE): New macro.
	* target-def.h (TARGET_ADDR_SPACE_POINTER_MODE): New target hook.
	(TARGET_ADDR_SPACE_NAME): Likewise.
	(TARGET_ADDR_SPACE_NUMBER): Likewise.
	(TARGET_ADDR_SPACE_CONVERSION_RTL): Likewise.
	(TARGET_VALID_ADDR_SPACE): Likewise.
	(TARGET_INITIALIZER): Incorporate the hooks above.
	* target.h (struct gcc_target): Add addr_space_pointer_mode,
	addr_space_name, addr_space_number, addr_space_conversion_rtl,
	valid_addr_space callbacks.
	* targhooks.h (default_addr_space_name): Declare.
	(default_addr_space_number): Likewise.
	(default_addr_space_conversion_rtl): Likewise.
	* targhooks.c (default_addr_space_name): New.
	(default_addr_space_conversion_rtl): Likewise.
	(default_addr_space_number): Likewise.
	* tree-pretty-print.c: Include target.h and target-def.h.
	(dump_generic_node): Output address space information.
	* tree-ssa-loop-ivopts.c (generic_type_for): If the pointer
	belongs to another address space, include that qualification in
	the type for the pointer returned.
	* tree-ssa.c (useless_type_conversion_p_1): Casts between pointers
	in different address spaces are never useless.
	(useless_type_conversion_p): Casts between two generic void
	pointers are useless.
	* tree.c (integer_pow2p): Handle non-generic pointer sizes.
	(tree_log2): Likewise.
	(tree_floor_log2): Likewise.
	(set_type_quals): Set TYPE_ADDR_SPACE.
	(build_pointer_type): Do not assume pointers are ptr_mode.
	* tree.h (OTHER_ADDR_SPACE_POINTER): New macro.
	(GENERIC_ADDR_SPACE_POINTER): Likewise.
	(TYPE_ADDR_SPACE): Likewise.
	(ENCODE_QUAL_ADDR_SPACE): Likewise.
	(DECODE_QUAL_ADDR_SPACE): Likewise.
	(TYPE_QUALS): Encode the address space in the qualifiers.
	(addr_space_t): New type.
	(struct tree_type): Add address_space field.
	* varasm.c (make_decl_rtl): Use the address space pointer mode,
	not necessarily Pmode.
	(default_addr_space_pointer_mode): New function.
	* doc/extend.texi (Named Address Spaces): New node.
	* doc/rtl.texi (Special Accessors): Document MEM_ADDR_SPACE.
	* doc/tm.texi (Misc): Document these new target hooks.

cp/
2008-08-28  Ben Elliston  <bje@au.ibm.com>

	* typeck.c (cp_type_quals): Use CONST_CAST_TREE on type.


diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/c-decl.c gcc-nas/gcc/c-decl.c
--- gcc-clean/gcc/c-decl.c	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/c-decl.c	2008-08-29 11:30:52.000000000 +1000
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3.  
 #include "except.h"
 #include "langhooks-def.h"
 #include "pointer-set.h"
+#include "targhooks.h"
 #include "gimple.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
@@ -2902,7 +2903,8 @@ shadow_tag_warned (const struct c_declsp
 	  else if (!declspecs->tag_defined_p
 		   && (declspecs->const_p
 		       || declspecs->volatile_p
-		       || declspecs->restrict_p))
+		       || declspecs->restrict_p
+		       || declspecs->address_space))
 	    {
 	      if (warned != 1)
 		pedwarn (input_location, 0,
@@ -2973,7 +2975,8 @@ shadow_tag_warned (const struct c_declsp
 
   if (!warned && !in_system_header && (declspecs->const_p
 				       || declspecs->volatile_p
-				       || declspecs->restrict_p))
+				       || declspecs->restrict_p
+				       || declspecs->address_space))
     {
       warning (0, "useless type qualifier in empty declaration");
       warned = 2;
@@ -2996,7 +2999,8 @@ quals_from_declspecs (const struct c_dec
 {
   int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0)
 	       | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
-	       | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0));
+	       | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)
+	       | (ENCODE_QUAL_ADDR_SPACE (specs->address_space)));
   gcc_assert (!specs->type
 	      && !specs->decl_attr
 	      && specs->typespec_word == cts_none
@@ -3960,6 +3964,7 @@ grokdeclarator (const struct c_declarato
   int constp;
   int restrictp;
   int volatilep;
+  int addr_space_p;
   int type_quals = TYPE_UNQUALIFIED;
   const char *name, *orig_name;
   bool funcdef_flag = false;
@@ -4074,6 +4079,7 @@ grokdeclarator (const struct c_declarato
   constp = declspecs->const_p + TYPE_READONLY (element_type);
   restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
   volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
+  addr_space_p = (declspecs->address_space > 0) + (TYPE_ADDR_SPACE (element_type) > 0);
   if (pedantic && !flag_isoc99)
     {
       if (constp > 1)
@@ -4083,15 +4089,88 @@ grokdeclarator (const struct c_declarato
       if (volatilep > 1)
 	pedwarn (input_location, OPT_pedantic, "duplicate %<volatile%>");
     }
+
+  if (!flag_iso)
+    {
+      addr_space_t as1 = declspecs->address_space;
+      addr_space_t as2 = TYPE_ADDR_SPACE (element_type);
+
+      if (as1 > 0 && as2 > 0 && as1 != as2)
+	error ("incompatible address space qualifiers %qs and %qs",
+	       targetm.addr_space_name (as1),
+	       targetm.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)
 		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
-		| (volatilep ? TYPE_QUAL_VOLATILE : 0));
+		| (volatilep ? TYPE_QUAL_VOLATILE : 0)
+		| (addr_space_p ? ENCODE_QUAL_ADDR_SPACE (declspecs->address_space) : 0));
 
   /* Warn about storage classes that are invalid for certain
      kinds of declarations (parameters, typenames, etc.).  */
 
+  if (((declarator->kind == cdk_pointer
+ 	&& (DECODE_QUAL_ADDR_SPACE (declarator->u.pointer_quals)) != 0)
+       || addr_space_p)
+      && targetm.addr_space_name == default_addr_space_name)
+     {
+       /* A mere warning is sure to result in improper semantics
+	  at runtime.  Don't bother to allow this to compile.  */
+       error ("extended address space not supported for this target");
+       return 0;
+     }
+
+  if (declarator->kind == cdk_pointer
+      ? (DECODE_QUAL_ADDR_SPACE (declarator->u.pointer_quals)) != 0
+      : addr_space_p)
+    {
+      const char *addrspace_name;
+
+      /* Either declspecs or the declarator identifies the address space.  */
+      if (declspecs->address_space)
+	addrspace_name = targetm.addr_space_name (declspecs->address_space);
+      else
+	addrspace_name = targetm.addr_space_name (DECODE_QUAL_ADDR_SPACE (declarator->u.pointer_quals));
+
+      if (decl_context == NORMAL)
+	{
+	  if (declarator->kind == cdk_function)
+	    error ("%qs specified for function %qs", addrspace_name, name);
+	  else
+	    {
+	      switch (storage_class)
+		{
+		case csc_auto:
+		  error ("%qs combined with %<auto%> qualifier for %qs", addrspace_name, name);
+		  break;
+		case csc_register:
+		  error ("%qs combined with %<register%> qualifier for %qs", addrspace_name, name);
+		  break;
+		case csc_none:
+		  if (current_function_scope)
+ 		    {
+ 		      error ("%<__ea%> specified for auto variable %qs", name);
+ 		      break;
+ 		    }
+		  break;
+		case csc_static:
+		  break;
+		case csc_extern:
+		  break;
+		case csc_typedef:
+		  break;
+		}
+	    }
+	}
+      else if (decl_context == PARM
+	       && declarator->kind != cdk_array)
+	error ("%qs specified for parameter %qs", addrspace_name, name);
+      else if (decl_context == FIELD)
+	error ("%qs specified for structure field %qs", addrspace_name, name);
+    }
+
   if (funcdef_flag
       && (threadp
 	  || storage_class == csc_auto
@@ -7109,9 +7188,29 @@ build_null_declspecs (void)
   ret->volatile_p = false;
   ret->restrict_p = false;
   ret->saturating_p = false;
+  ret->address_space = 0;
   return ret;
 }
 
+/* Add the address space ADDRSPACE to the declaration specifiers
+   SPECS, returning SPECS.  */
+
+struct c_declspecs *
+declspecs_add_addrspace (struct c_declspecs *specs, tree addrspace)
+{
+  specs->non_sc_seen_p = true;
+  specs->declspecs_seen_p = true;
+
+  if (specs->address_space > 0
+      && specs->address_space != targetm.addr_space_number (addrspace))
+    error ("incompatible address space qualifiers %qs and %qs",
+	   targetm.addr_space_name (targetm.addr_space_number (addrspace)),
+	   targetm.addr_space_name (specs->address_space));
+
+  specs->address_space = targetm.addr_space_number (addrspace);
+  return specs;
+}
+
 /* Add the type qualifier QUAL to the declaration specifiers SPECS,
    returning SPECS.  */
 
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/c-objc-common.c gcc-nas/gcc/c-objc-common.c
--- gcc-clean/gcc/c-objc-common.c	2008-04-03 15:14:25.000000000 +1100
+++ gcc-nas/gcc/c-objc-common.c	2008-08-27 11:36:43.000000000 +1000
@@ -187,6 +187,10 @@ c_initialize_diagnostics (diagnostic_con
 int
 c_types_compatible_p (tree x, tree y)
 {
+  if (TYPE_ADDR_SPACE (strip_array_types (x))
+      != TYPE_ADDR_SPACE (strip_array_types (y)))
+    return false;
+
   return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
 }
 
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/convert.c gcc-nas/gcc/convert.c
--- gcc-clean/gcc/convert.c	2008-05-11 14:37:53.000000000 +1000
+++ gcc-nas/gcc/convert.c	2008-08-27 11:36:43.000000000 +1000
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  
 #include "langhooks.h"
 #include "real.h"
 #include "fixed-value.h"
+#include "target.h"
 
 /* Convert EXPR to some pointer or reference type TYPE.
    EXPR must be pointer, reference, integer, enumeral, or literal zero;
@@ -58,11 +59,16 @@ convert_to_pointer (tree type, tree expr
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
-      if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE)
-	expr = fold_build1 (NOP_EXPR,
-                            lang_hooks.types.type_for_size (POINTER_SIZE, 0),
-			    expr);
-      return fold_build1 (CONVERT_EXPR, type, expr);
+    {
+      int pointer_size =
+	TYPE_ADDR_SPACE (TREE_TYPE (type))
+	? GET_MODE_BITSIZE (targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (type))))
+	: POINTER_SIZE;
+
+      if (TYPE_PRECISION (TREE_TYPE (expr)) != pointer_size)
+	expr = fold_build1 (NOP_EXPR, lang_hooks.types.type_for_size (pointer_size, 0), expr);
+    }
+    return fold_build1 (CONVERT_EXPR, type, expr);
 
 
     default:
@@ -448,15 +454,24 @@ convert_to_integer (tree type, tree expr
     {
     case POINTER_TYPE:
     case REFERENCE_TYPE:
-      if (integer_zerop (expr))
-	return build_int_cst (type, 0);
+      {
+ 	int pointer_size;
+
+ 	if (integer_zerop (expr))
+ 	  return build_int_cst (type, 0);
 
-      /* Convert to an unsigned integer of the correct width first,
-	 and from there widen/truncate to the required type.  */
-      expr = fold_build1 (CONVERT_EXPR,
-			  lang_hooks.types.type_for_size (POINTER_SIZE, 0),
-			  expr);
-      return fold_convert (type, expr);
+ 	/* Convert to an unsigned integer of the correct width first,
+ 	   and from there widen/truncate to the required type.  */
+ 	pointer_size =
+ 	  TYPE_ADDR_SPACE (strip_array_types (TREE_TYPE (intype)))
+	  ? GET_MODE_BITSIZE (targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (intype))))
+ 	  : POINTER_SIZE;
+
+ 	expr = fold_build1 (CONVERT_EXPR,
+ 			    lang_hooks.types.type_for_size (pointer_size, 0),
+ 			    expr);
+ 	return fold_build1 (NOP_EXPR, type, expr);
+      }
 
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/cp/typeck.c gcc-nas/gcc/cp/typeck.c
--- gcc-clean/gcc/cp/typeck.c	2008-08-27 10:32:00.000000000 +1000
+++ gcc-nas/gcc/cp/typeck.c	2008-08-27 12:00:14.000000000 +1000
@@ -7108,7 +7108,7 @@ cp_type_quals (const_tree type)
   type = strip_array_types (CONST_CAST_TREE(type));
   if (type == error_mark_node)
     return TYPE_UNQUALIFIED;
-  return TYPE_QUALS (type);
+  return TYPE_QUALS (CONST_CAST_TREE (type));
 }
 
 /* Returns nonzero if the TYPE is const from a C++ perspective: look inside
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/c-parser.c gcc-nas/gcc/c-parser.c
--- gcc-clean/gcc/c-parser.c	2008-08-22 09:28:16.000000000 +1000
+++ gcc-nas/gcc/c-parser.c	2008-08-28 17:00:35.000000000 +1000
@@ -130,6 +130,8 @@ typedef enum c_id_kind {
   C_ID_TYPENAME,
   /* An identifier declared as an Objective-C class name.  */
   C_ID_CLASSNAME,
+  /* An address space identifier.  */
+  C_ID_ADDRSPACE,
   /* Not an identifier.  */
   C_ID_NONE
 } c_id_kind;
@@ -256,6 +258,11 @@ c_lex_one_token (c_parser *parser, c_tok
 		break;
 	      }
 	  }
+	else if (targetm.valid_addr_space (token->value))
+	  {
+	    token->id_kind = C_ID_ADDRSPACE;
+	    break;
+	  }
 	else if (c_dialect_objc ())
 	  {
 	    tree objc_interface_decl = objc_is_class_name (token->value);
@@ -352,6 +359,8 @@ c_token_starts_typename (c_token *token)
 	{
 	case C_ID_ID:
 	  return false;
+	case C_ID_ADDRSPACE:
+	  return true;
 	case C_ID_TYPENAME:
 	  return true;
 	case C_ID_CLASSNAME:
@@ -422,6 +431,8 @@ c_token_starts_declspecs (c_token *token
 	{
 	case C_ID_ID:
 	  return false;
+	case C_ID_ADDRSPACE:
+	  return true;
 	case C_ID_TYPENAME:
 	  return true;
 	case C_ID_CLASSNAME:
@@ -1391,6 +1402,7 @@ c_parser_asm_definition (c_parser *parse
      const
      restrict
      volatile
+     address-space-qualifier
 
    (restrict is new in C99.)
 
@@ -1399,6 +1411,12 @@ c_parser_asm_definition (c_parser *parse
    declaration-specifiers:
      attributes declaration-specifiers[opt]
 
+   type-qualifier:
+     address-space
+
+   address-space:
+     identifier recognized by the target
+
    storage-class-specifier:
      __thread
 
@@ -1438,6 +1456,15 @@ c_parser_declspecs (c_parser *parser, st
 	{
 	  tree value = c_parser_peek_token (parser)->value;
 	  c_id_kind kind = c_parser_peek_token (parser)->id_kind;
+
+	  if (kind == C_ID_ADDRSPACE)
+	    {
+	      declspecs_add_addrspace (specs, c_parser_peek_token (parser)->value);
+	      c_parser_consume_token (parser);
+	      attrs_ok = true;
+	      continue;
+	    }
+
 	  /* This finishes the specifiers unless a type name is OK, it
 	     is declared as a type name and a type name hasn't yet
 	     been seen.  */
@@ -5498,6 +5525,14 @@ c_parser_postfix_expression_after_paren_
   finish_init ();
   maybe_warn_string_init (type, init);
 
+  if (type != error_mark_node
+      && TYPE_ADDR_SPACE (strip_array_types (type))
+      && current_function_decl)
+    {
+      error ("compound literal qualified by address-space qualifier");
+      type = error_mark_node;
+    }
+
   if (!flag_isoc99)
     pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals");
   expr.value = build_compound_literal (type, init.value);
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/c-pretty-print.c gcc-nas/gcc/c-pretty-print.c
--- gcc-clean/gcc/c-pretty-print.c	2008-07-29 09:09:02.000000000 +1000
+++ gcc-nas/gcc/c-pretty-print.c	2008-07-29 16:14:41.000000000 +1000
@@ -29,6 +29,8 @@ along with GCC; see the file COPYING3.  
 #include "c-tree.h"
 #include "tree-iterator.h"
 #include "diagnostic.h"
+#include "target.h"
+#include "target-def.h"
 
 /* The pretty-printer code is primarily designed to closely follow
    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
@@ -220,7 +222,11 @@ pp_c_space_for_pointer_operator (c_prett
        const
        restrict                              -- C99
        __restrict__                          -- GNU C
-       volatile    */
+       address-space-qualifier		     -- GNU C
+       volatile
+
+   address-space-qualifier:
+       identifier			     -- GNU C  */
 
 void
 pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
@@ -240,6 +246,12 @@ pp_c_type_qualifier_list (c_pretty_print
     pp_c_cv_qualifier (pp, "volatile");
   if (qualifiers & TYPE_QUAL_RESTRICT)
     pp_c_cv_qualifier (pp, flag_isoc99 ? "restrict" : "__restrict__");
+
+  if (TYPE_ADDR_SPACE (t))
+    {
+      const char *as = targetm.addr_space_name (TYPE_ADDR_SPACE (t));
+      pp_c_identifier (pp, as);
+    }
 }
 
 /* pointer:
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/c-tree.h gcc-nas/gcc/c-tree.h
--- gcc-clean/gcc/c-tree.h	2008-08-22 09:28:16.000000000 +1000
+++ gcc-nas/gcc/c-tree.h	2008-08-27 12:00:32.000000000 +1000
@@ -286,6 +286,8 @@ struct c_declspecs {
   BOOL_BITFIELD restrict_p : 1;
   /* Whether "_Sat" was specified.  */
   BOOL_BITFIELD saturating_p : 1;
+  /* The address space that the declaration belongs to.  */
+  addr_space_t address_space;
 };
 
 /* The various kinds of declarators in C.  */
@@ -515,6 +517,7 @@ extern struct c_declspecs *declspecs_add
 					       struct c_typespec);
 extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
 extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
+extern struct c_declspecs *declspecs_add_addrspace (struct c_declspecs *, tree);
 extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
 
 /* in c-objc-common.c */
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/c-typeck.c gcc-nas/gcc/c-typeck.c
--- gcc-clean/gcc/c-typeck.c	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/c-typeck.c	2008-08-27 12:04:08.000000000 +1000
@@ -917,7 +917,7 @@ comptypes_internal (const_tree type1, co
 
   /* Qualifiers must match. C99 6.7.3p9 */
 
-  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
+  if (TYPE_QUALS (CONST_CAST_TREE (t1)) != TYPE_QUALS (CONST_CAST_TREE (t2)))
     return 0;
 
   /* Allow for two different type nodes which have essentially the same
@@ -8205,6 +8205,16 @@ build_binary_op (enum tree_code code, tr
 		  && TREE_CODE (tt1) == FUNCTION_TYPE)
 		pedwarn (input_location, OPT_pedantic, "ISO C forbids "
 			 "comparison of %<void *%> with function pointer");
+
+	      /* If this operand is a pointer into another address
+		 space, make the result of the comparison such a
+		 pointer also.  */
+	      if (OTHER_ADDR_SPACE_POINTER_TYPE_P (type0))
+		{
+		  int qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (TREE_TYPE (type0)));
+		  result_type = build_pointer_type
+		    (build_qualified_type (void_type_node, qual));
+		}
 	    }
 	  else if (VOID_TYPE_P (tt1))
 	    {
@@ -8212,6 +8222,16 @@ build_binary_op (enum tree_code code, tr
 		  && TREE_CODE (tt0) == FUNCTION_TYPE)
 		pedwarn (input_location, OPT_pedantic, "ISO C forbids "
 			 "comparison of %<void *%> with function pointer");
+
+	      /* If this operand is a pointer into another address
+		 space, make the result of the comparison such a
+		 pointer also.  */
+	      if (OTHER_ADDR_SPACE_POINTER_TYPE_P (type1))
+		{
+		  int qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (TREE_TYPE (type1)));
+		  result_type = build_pointer_type
+		    (build_qualified_type (void_type_node, qual));
+		}
 	    }
 	  else
 	    /* Avoid warning about the volatile ObjC EH puts on decls.  */
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/doc/extend.texi gcc-nas/gcc/doc/extend.texi
--- gcc-clean/gcc/doc/extend.texi	2008-08-29 11:32:36.000000000 +1000
+++ gcc-nas/gcc/doc/extend.texi	2008-08-22 10:04:18.000000000 +1000
@@ -37,6 +37,7 @@ extensions, accepted by GCC in C89 mode 
 * Decimal Float::       Decimal Floating Types. 
 * Hex Floats::          Hexadecimal floating-point constants.
 * Fixed-Point::         Fixed-Point Types.
+* Named Address Spaces::Named address spaces.
 * Zero Length::         Zero-length arrays.
 * Variable Length::     Arrays whose length is computed at run time.
 * Empty Structures::    Structures with no members.
@@ -1119,6 +1120,31 @@ Pragmas to control overflow and rounding
 
 Fixed-point types are supported by the DWARF2 debug information format.
 
+@node Named Address Spaces
+@section Named address spaces
+@cindex named address spaces
+
+As an extension, the GNU C compiler supports named address spaces as
+defined in the N1275 draft of ISO/IEC DTR 18037.  Support for named
+address spaces in GCC will evolve as the draft technical report changes.
+Calling conventions for any target might also change.  At present, only
+the SPU target supports other address spaces.  On the SPU target, for
+example, variables may be declared as belonging to another address space
+by qualifying the type with the @code{__ea} address space identifier:
+
+@smallexample
+extern int __ea i;
+@end smallexample
+
+When the variable @code{i} is accessed, the compiler will generate
+special code to access this variable.  It may use runtime library
+support, or generate special machine instructions to access that address
+space.
+
+The @code{__ea} identifier may be used exactly like any other C type
+qualifier (e.g., @code{const} or @code{volatile}).  See the N1275
+document for more details.
+
 @node Zero Length
 @section Arrays of Length Zero
 @cindex arrays of length zero
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/doc/rtl.texi gcc-nas/gcc/doc/rtl.texi
--- gcc-clean/gcc/doc/rtl.texi	2008-06-30 10:09:13.000000000 +1000
+++ gcc-nas/gcc/doc/rtl.texi	2008-07-15 15:46:04.000000000 +1000
@@ -420,6 +420,11 @@ the size is implied by the mode.
 @findex MEM_ALIGN
 @item MEM_ALIGN (@var{x})
 The known alignment in bits of the memory reference.
+
+@findex MEM_ADDR_SPACE
+@item MEM_ADDR_SPACE (@var{x})
+The address space of the memory reference.  This will commonly be zero
+for the generic address space.
 @end table
 
 @item REG
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/doc/tm.texi gcc-nas/gcc/doc/tm.texi
--- gcc-clean/gcc/doc/tm.texi	2008-08-27 07:16:34.000000000 +1000
+++ gcc-nas/gcc/doc/tm.texi	2008-08-27 11:59:01.000000000 +1000
@@ -10575,3 +10575,37 @@ cannot safely move arguments from the re
 to the stack.  Therefore, this hook should return true in general, but
 false for naked functions.  The default implementation always returns true.
 @end deftypefn
+
+@deftypefn {Target Hook} {enum machine_mode} TARGET_ADDR_SPACE_POINTER_MODE (int @var{address_space})
+Define this to return a pointer mode for a given @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} {const char *} TARGET_ADDR_SPACE_NAME (int @var{address_space})
+Define this to return a string that describes the @var{address_space}.
+As this hook should never be called for targets that do not support
+named address spaces, the default version of this hook will cause the
+compiler to abort.
+@end deftypefn
+
+@deftypefn {Target Hook} {unsigned char} TARGET_ADDR_SPACE_NUMBER (tree @var{address_space})
+Define this to return a target-defined address space number for the
+given @var{address_space}.  As this hook should never be called for
+targets that do not support named address spaces, the default version
+of this hook will cause the compiler to abort.
+@end deftypefn
+
+@deftypefn {Target Hook} {rtx (*int, int)} TARGET_ADDR_SPACE_CONVERSION_RTL (int @var{from}, int @var{to})
+Define this to return a pointer to a function that generates the RTL for
+a pointer conversion from the @var{from} address space to the @var{to}
+address space.  As this hook should never be called for targets that do
+not support named address spaces, the default version of this hook will
+cause the compiler to abort.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_VALID_ADDR_SPACE (tree @var{address_space})
+Define this to return true if the @var{address_space} is recognized
+for the target.  The default version of this hook unconditionally
+returns false.
+@end deftypefn
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/dwarf2out.c gcc-nas/gcc/dwarf2out.c
--- gcc-clean/gcc/dwarf2out.c	2008-08-26 09:15:04.000000000 +1000
+++ gcc-nas/gcc/dwarf2out.c	2008-08-27 12:00:36.000000000 +1000
@@ -9496,6 +9496,9 @@ modified_type_die (tree type, int is_con
       add_AT_unsigned (mod_type_die, DW_AT_byte_size,
 		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
       item_type = TREE_TYPE (type);
+      if (TYPE_ADDR_SPACE (strip_array_types (item_type)))
+	add_AT_unsigned (mod_type_die, DW_AT_address_class,
+			 TYPE_ADDR_SPACE (item_type));
     }
   else if (code == REFERENCE_TYPE)
     {
@@ -9503,6 +9506,9 @@ modified_type_die (tree type, int is_con
       add_AT_unsigned (mod_type_die, DW_AT_byte_size,
 		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
       item_type = TREE_TYPE (type);
+      if (TYPE_ADDR_SPACE (strip_array_types (item_type)))
+	add_AT_unsigned (mod_type_die, DW_AT_address_class,
+			 TYPE_ADDR_SPACE (item_type));
     }
   else if (is_subrange_type (type))
     {
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/emit-rtl.c gcc-nas/gcc/emit-rtl.c
--- gcc-clean/gcc/emit-rtl.c	2008-07-31 13:23:06.000000000 +1000
+++ gcc-nas/gcc/emit-rtl.c	2008-08-27 11:36:43.000000000 +1000
@@ -193,7 +193,7 @@ static rtx lookup_const_fixed (rtx);
 static hashval_t mem_attrs_htab_hash (const void *);
 static int mem_attrs_htab_eq (const void *, const void *);
 static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int,
-				 enum machine_mode);
+				 addr_space_t, enum machine_mode);
 static hashval_t reg_attrs_htab_hash (const void *);
 static int reg_attrs_htab_eq (const void *, const void *);
 static reg_attrs *get_reg_attrs (tree, int);
@@ -321,7 +321,7 @@ mem_attrs_htab_eq (const void *x, const 
 
 static mem_attrs *
 get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
-	       unsigned int align, enum machine_mode mode)
+	       unsigned int align, addr_space_t addrspace, enum machine_mode mode)
 {
   mem_attrs attrs;
   void **slot;
@@ -341,6 +341,7 @@ get_mem_attrs (alias_set_type alias, tre
   attrs.offset = offset;
   attrs.size = size;
   attrs.align = align;
+  attrs.addrspace = addrspace;
 
   slot = htab_find_slot (mem_attrs_htab, &attrs, INSERT);
   if (*slot == 0)
@@ -1748,7 +1749,9 @@ set_mem_attributes_minus_bitpos (rtx ref
 
   /* Now set the attributes we computed above.  */
   MEM_ATTRS (ref)
-    = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref));
+    = get_mem_attrs (alias, expr, offset, size, align,
+		     TYPE_ADDR_SPACE (strip_array_types (type)),
+		     GET_MODE (ref));
 
   /* If this is already known to be a scalar or aggregate, we are done.  */
   if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
@@ -1776,7 +1779,7 @@ set_mem_attrs_from_reg (rtx mem, rtx reg
   MEM_ATTRS (mem)
     = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
 		     GEN_INT (REG_OFFSET (reg)),
-		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
+		     MEM_SIZE (mem), MEM_ALIGN (mem), MEM_ADDR_SPACE (mem), GET_MODE (mem));
 }
 
 /* Set the alias set of MEM to SET.  */
@@ -1790,17 +1793,27 @@ set_mem_alias_set (rtx mem, alias_set_ty
 #endif
 
   MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
-				   MEM_SIZE (mem), MEM_ALIGN (mem),
+				   MEM_SIZE (mem), MEM_ALIGN (mem), MEM_ADDR_SPACE (mem),
 				   GET_MODE (mem));
 }
 
+/* Set the address space of MEM to ADDRSPACE (target-defined).  */
+
+void
+set_mem_addr_space (rtx mem, addr_space_t addrspace)
+{
+  MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
+				   MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem),
+				   addrspace, GET_MODE (mem));
+}
+
 /* Set the alignment of MEM to ALIGN bits.  */
 
 void
 set_mem_align (rtx mem, unsigned int align)
 {
   MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
-				   MEM_OFFSET (mem), MEM_SIZE (mem), align,
+				   MEM_OFFSET (mem), MEM_SIZE (mem), align, MEM_ADDR_SPACE (mem),
 				   GET_MODE (mem));
 }
 
@@ -1811,7 +1824,7 @@ set_mem_expr (rtx mem, tree expr)
 {
   MEM_ATTRS (mem)
     = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
-		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
+		     MEM_SIZE (mem), MEM_ALIGN (mem), MEM_ADDR_SPACE (mem), GET_MODE (mem));
 }
 
 /* Set the offset of MEM to OFFSET.  */
@@ -1820,7 +1833,7 @@ void
 set_mem_offset (rtx mem, rtx offset)
 {
   MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
-				   offset, MEM_SIZE (mem), MEM_ALIGN (mem),
+				   offset, MEM_SIZE (mem), MEM_ALIGN (mem), MEM_ADDR_SPACE (mem),
 				   GET_MODE (mem));
 }
 
@@ -1830,7 +1843,7 @@ void
 set_mem_size (rtx mem, rtx size)
 {
   MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
-				   MEM_OFFSET (mem), size, MEM_ALIGN (mem),
+				   MEM_OFFSET (mem), size, MEM_ALIGN (mem), MEM_ADDR_SPACE (mem),
 				   GET_MODE (mem));
 }
 
@@ -1898,7 +1911,7 @@ change_address (rtx memref, enum machine
     }
 
   MEM_ATTRS (new_rtx)
-    = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
+    = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, MEM_ADDR_SPACE (memref), mmode);
 
   return new_rtx;
 }
@@ -1965,7 +1978,8 @@ adjust_address_1 (rtx memref, enum machi
     size = plus_constant (MEM_SIZE (memref), -offset);
 
   MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
-				   memoffset, size, memalign, GET_MODE (new_rtx));
+				   memoffset, size, memalign, MEM_ADDR_SPACE (memref),
+				   GET_MODE (new_rtx));
 
   /* At some point, we should validate that this offset is within the object,
      if all the appropriate values are known.  */
@@ -2023,7 +2037,7 @@ offset_address (rtx memref, rtx offset, 
   MEM_ATTRS (new_rtx)
     = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
 		     MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
-		     GET_MODE (new_rtx));
+		     MEM_ADDR_SPACE (memref), GET_MODE (new_rtx));
   return new_rtx;
 }
 
@@ -2127,7 +2141,7 @@ widen_memory_access (rtx memref, enum ma
   /* ??? Maybe use get_alias_set on any remaining expression.  */
 
   MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
-				   MEM_ALIGN (new_rtx), mode);
+				   MEM_ALIGN (new_rtx), MEM_ADDR_SPACE (new_rtx), mode);
 
   return new_rtx;
 }
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/emit-rtl.h gcc-nas/gcc/emit-rtl.h
--- gcc-clean/gcc/emit-rtl.h	2008-04-03 15:14:25.000000000 +1100
+++ gcc-nas/gcc/emit-rtl.h	2008-07-15 15:46:04.000000000 +1000
@@ -26,6 +26,9 @@ extern void set_mem_alias_set (rtx, alia
 /* Set the alignment of MEM to ALIGN bits.  */
 extern void set_mem_align (rtx, unsigned int);
 
+/* Set the address space of MEM to ADDRSPACE.  */
+extern void set_mem_addr_space (rtx, unsigned char);
+
 /* Set the expr for MEM to EXPR.  */
 extern void set_mem_expr (rtx, tree);
 
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/explow.c gcc-nas/gcc/explow.c
--- gcc-clean/gcc/explow.c	2008-08-17 09:48:19.000000000 +1000
+++ gcc-nas/gcc/explow.c	2008-08-19 20:18:53.000000000 +1000
@@ -414,7 +414,8 @@ memory_address (enum machine_mode mode, 
 {
   rtx oldx = x;
 
-  x = convert_memory_address (Pmode, x);
+  if (MEM_P (x) && !targetm.valid_pointer_mode (GET_MODE (x)))
+    x = convert_memory_address (Pmode, x);
 
   /* By passing constant addresses through registers
      we get a chance to cse them.  */
@@ -484,6 +485,8 @@ memory_address (enum machine_mode mode, 
 
       /* Last resort: copy the value to a register, since
 	 the register is a valid address.  */
+      else if (targetm.valid_pointer_mode (GET_MODE (x)))
+	x = force_reg (GET_MODE (x), x);
       else
 	x = force_reg (Pmode, x);
     }
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/expr.c gcc-nas/gcc/expr.c
--- gcc-clean/gcc/expr.c	2008-08-19 06:55:43.000000000 +1000
+++ gcc-nas/gcc/expr.c	2008-08-19 20:16:16.000000000 +1000
@@ -6894,17 +6894,22 @@ expand_expr_addr_expr (tree exp, rtx tar
 		       enum expand_modifier modifier)
 {
   enum machine_mode rmode;
+  enum machine_mode addrmode;
   rtx result;
 
   /* Target mode of VOIDmode says "whatever's natural".  */
   if (tmode == VOIDmode)
     tmode = TYPE_MODE (TREE_TYPE (exp));
 
+  addrmode = Pmode;
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (TREE_TYPE (exp)))
+    addrmode = targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (exp)));
+
   /* 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 != addrmode && tmode != ptr_mode)
+    tmode = addrmode;
 
   result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
 				    tmode, modifier);
@@ -7142,6 +7147,8 @@ expand_expr_real_1 (tree exp, rtx target
   int ignore;
   tree context, subexp0, subexp1;
   bool reduce_bit_field;
+  rtx (*genfn) (rtx, rtx);
+
 #define REDUCE_BIT_FIELD(expr)	(reduce_bit_field			  \
 				 ? reduce_to_bit_field_precision ((expr), \
 								  target, \
@@ -8105,6 +8112,27 @@ expand_expr_real_1 (tree exp, rtx target
 	  return target;
 	}
 
+      /* Handle casts of pointers to/from address space qualified
+	 pointers.  */
+      if (OTHER_ADDR_SPACE_POINTER_TYPE_P (type)
+	  && GENERIC_ADDR_SPACE_POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
+	{
+	  rtx reg = gen_reg_rtx (TYPE_MODE (type));
+	  op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, modifier);
+	  genfn = targetm.addr_space_conversion_rtl (0, 1);
+	  emit_insn (genfn (reg, op0));
+	  return reg;
+	}
+      else if (GENERIC_ADDR_SPACE_POINTER_TYPE_P (type)
+	       && (OTHER_ADDR_SPACE_POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0)))))
+	{
+	  rtx reg = gen_reg_rtx (Pmode);
+	  op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, modifier);
+	  genfn = targetm.addr_space_conversion_rtl (1, 0);
+	  emit_insn (genfn (reg, op0));
+	  return reg;
+	}
+
       if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
 	{
 	  op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode,
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/fold-const.c gcc-nas/gcc/fold-const.c
--- gcc-clean/gcc/fold-const.c	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/fold-const.c	2008-08-27 11:59:23.000000000 +1000
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  
 #include "hashtab.h"
 #include "langhooks.h"
 #include "md5.h"
+#include "target.h"
 #include "gimple.h"
 
 /* Nonzero if we are folding constants inside an initializer; zero
@@ -203,8 +204,10 @@ fit_double_type (unsigned HOST_WIDE_INT 
   unsigned int prec;
   int sign_extended_type;
 
-  if (POINTER_TYPE_P (type)
-      || TREE_CODE (type) == OFFSET_TYPE)
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (type))
+    prec = GET_MODE_BITSIZE (targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (type)));
+  else if (POINTER_TYPE_P (type)
+	   || TREE_CODE (type) == OFFSET_TYPE)
     prec = POINTER_SIZE;
   else
     prec = TYPE_PRECISION (type);
@@ -2396,7 +2399,9 @@ fold_convert_const (enum tree_code code,
   if (TREE_TYPE (arg1) == type)
     return arg1;
 
-  if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (type))
+    return NULL_TREE;
+  else if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
       || TREE_CODE (type) == OFFSET_TYPE)
     {
       if (TREE_CODE (arg1) == INTEGER_CST)
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/langhooks.c gcc-nas/gcc/langhooks.c
--- gcc-clean/gcc/langhooks.c	2008-07-30 09:33:35.000000000 +1000
+++ gcc-nas/gcc/langhooks.c	2008-08-27 11:36:43.000000000 +1000
@@ -284,7 +284,7 @@ lhd_tree_dump_dump_tree (void *di ATTRIB
 int
 lhd_tree_dump_type_quals (const_tree t)
 {
-  return TYPE_QUALS (t);
+  return TYPE_QUALS (CONST_CAST_TREE (t));
 }
 
 /* lang_hooks.expr_size: Determine the size of the value of an expression T
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/output.h gcc-nas/gcc/output.h
--- gcc-clean/gcc/output.h	2008-04-28 12:07:15.000000000 +1000
+++ gcc-nas/gcc/output.h	2008-06-16 16:22:24.000000000 +1000
@@ -616,6 +616,7 @@ extern void default_internal_label (FILE
 extern void default_file_start (void);
 extern void file_end_indicate_exec_stack (void);
 extern bool default_valid_pointer_mode (enum machine_mode);
+extern enum machine_mode default_addr_space_pointer_mode (int);
 
 extern void default_elf_asm_output_external (FILE *file, tree,
 					     const char *);
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/print-rtl.c gcc-nas/gcc/print-rtl.c
--- gcc-clean/gcc/print-rtl.c	2008-04-17 10:45:38.000000000 +1000
+++ gcc-nas/gcc/print-rtl.c	2008-08-11 11:51:39.000000000 +1000
@@ -556,6 +556,9 @@ print_rtx (const_rtx in_rtx)
       if (MEM_ALIGN (in_rtx) != 1)
 	fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
 
+      if (MEM_ADDR_SPACE (in_rtx))
+	fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
+
       fputc (']', outfile);
       break;
 
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/print-tree.c gcc-nas/gcc/print-tree.c
--- gcc-clean/gcc/print-tree.c	2008-08-07 14:06:16.000000000 +1000
+++ gcc-nas/gcc/print-tree.c	2008-08-28 16:32:16.000000000 +1000
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3.  
 #include "tree-iterator.h"
 #include "diagnostic.h"
 #include "tree-flow.h"
+#include "target.h"
+#include "target-def.h"
 
 /* Define the hash table of nodes already seen.
    Such nodes are not repeated; brief cross-references are used.  */
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/rtl.h gcc-nas/gcc/rtl.h
--- gcc-clean/gcc/rtl.h	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/rtl.h	2008-08-28 16:39:02.000000000 +1000
@@ -142,10 +142,11 @@ typedef struct
 typedef struct mem_attrs GTY(())
 {
   alias_set_type alias;		/* Memory alias set.  */
+  unsigned int align;		/* Alignment of MEM in bits.  */
   tree expr;			/* expr corresponding to MEM.  */
   rtx offset;			/* Offset from start of DECL, as CONST_INT.  */
   rtx size;			/* Size in bytes, as a CONST_INT.  */
-  unsigned int align;		/* Alignment of MEM in bits.  */
+  unsigned char addrspace;	/* Address space (0 for generic).  */
 } mem_attrs;
 
 /* Structure used to describe the attributes of a REG in similar way as
@@ -1207,6 +1208,10 @@ do {						\
    RTX that is always a CONST_INT.  */
 #define MEM_OFFSET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->offset)
 
+/* For a MEM rtx, the address space.  If 0, the MEM belongs to the
+   generic address space.  */
+#define MEM_ADDR_SPACE(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->addrspace)
+
 /* For a MEM rtx, the size in bytes of the MEM, if known, as an RTX that
    is always a CONST_INT.  */
 #define MEM_SIZE(RTX)							\
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/target-def.h gcc-nas/gcc/target-def.h
--- gcc-clean/gcc/target-def.h	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/target-def.h	2008-07-31 13:42:01.000000000 +1000
@@ -437,6 +437,26 @@
 #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_NAME
+#define TARGET_ADDR_SPACE_NAME default_addr_space_name
+#endif
+
+#ifndef TARGET_ADDR_SPACE_NUMBER
+#define TARGET_ADDR_SPACE_NUMBER default_addr_space_number
+#endif
+
+#ifndef TARGET_ADDR_SPACE_CONVERSION_RTL
+#define TARGET_ADDR_SPACE_CONVERSION_RTL default_addr_space_conversion_rtl
+#endif
+
+#ifndef TARGET_VALID_ADDR_SPACE
+#define TARGET_VALID_ADDR_SPACE hook_bool_const_tree_false
+#endif
+
 #ifndef TARGET_SCALAR_MODE_SUPPORTED_P
 #define TARGET_SCALAR_MODE_SUPPORTED_P default_scalar_mode_supported_p
 #endif
@@ -862,6 +882,11 @@
   TARGET_MIN_DIVISIONS_FOR_RECIP_MUL,		\
   TARGET_MODE_REP_EXTENDED,			\
   TARGET_VALID_POINTER_MODE,                    \
+  TARGET_ADDR_SPACE_POINTER_MODE,		\
+  TARGET_ADDR_SPACE_NAME,			\
+  TARGET_ADDR_SPACE_NUMBER,			\
+  TARGET_ADDR_SPACE_CONVERSION_RTL,		\
+  TARGET_VALID_ADDR_SPACE,			\
   TARGET_SCALAR_MODE_SUPPORTED_P,		\
   TARGET_VECTOR_MODE_SUPPORTED_P,               \
   TARGET_VECTOR_OPAQUE_P,			\
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/target.h gcc-nas/gcc/target.h
--- gcc-clean/gcc/target.h	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/target.h	2008-08-27 11:55:29.000000000 +1000
@@ -627,6 +627,21 @@ struct gcc_target
   /* True if MODE is valid for a pointer in __attribute__((mode("MODE"))).  */
   bool (* valid_pointer_mode) (enum machine_mode mode);
 
+  /* MODE to use for a pointer into another address space.  */
+  enum machine_mode (* addr_space_pointer_mode) (int);
+
+  /* Function to map an address space to a descriptive string.  */
+  const char * (* addr_space_name) (int);
+
+  /* Function to map an address space to a descriptive string.  */
+  unsigned char (* addr_space_number) (const_tree);
+
+  /* Function to return a gen function for the pointer conversion.  */
+  rtx (* (* addr_space_conversion_rtl) (int, int)) (rtx, rtx);
+
+  /* True if an identifier that is a valid address space.  */
+  bool (* valid_addr_space) (const_tree);
+
   /* True if MODE is valid for the target.  By "valid", we mean able to
      be manipulated in non-trivial ways.  In particular, this means all
      the arithmetic is supported.  */
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/targhooks.c gcc-nas/gcc/targhooks.c
--- gcc-clean/gcc/targhooks.c	2008-07-24 13:24:12.000000000 +1000
+++ gcc-nas/gcc/targhooks.c	2008-08-27 11:48:15.000000000 +1000
@@ -703,6 +703,33 @@ default_builtin_vector_alignment_reachab
   return true;
 }
 
+/* The default hook for TARGET_ADDR_SPACE_NAME.  This hook should
+   never be called for targets with only a generic address space.  */
+
+const char *
+default_addr_space_name (int addrspace ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
+/* The default hook for TARGET_ADDR_SPACE_CONVERSION_RTL. This hook
+   should never be called for targets with only a generic address
+   space.  */
+
+rtx (* default_addr_space_conversion_rtl (int from ATTRIBUTE_UNUSED,
+					  int to ATTRIBUTE_UNUSED)) (rtx, rtx)
+{
+  gcc_unreachable ();
+}
+
+/* The default hook for TARGET_ADDR_SPACE_NUMBER.  This hook should
+   never be called for targets with only a generic address space.  */
+
+unsigned char default_addr_space_number (const_tree ident ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
 bool
 default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
 {
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/targhooks.h gcc-nas/gcc/targhooks.h
--- gcc-clean/gcc/targhooks.h	2008-07-24 13:24:12.000000000 +1000
+++ gcc-nas/gcc/targhooks.h	2008-08-27 11:48:08.000000000 +1000
@@ -100,3 +100,6 @@ extern tree default_emutls_var_init (tre
 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_can_inline_p (tree, tree);
+extern const char *default_addr_space_name (int);
+extern unsigned char default_addr_space_number (const_tree);
+extern rtx (*default_addr_space_conversion_rtl (int, int)) (rtx, rtx);
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/tree.c gcc-nas/gcc/tree.c
--- gcc-clean/gcc/tree.c	2008-08-29 11:32:47.000000000 +1000
+++ gcc-nas/gcc/tree.c	2008-08-27 11:59:15.000000000 +1000
@@ -1476,8 +1476,13 @@ 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)));
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (TREE_TYPE (expr)))
+    prec = GET_MODE_BITSIZE (targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (expr))));
+  else if (POINTER_TYPE_P (TREE_TYPE (expr)))
+    prec = POINTER_SIZE;
+  else
+    prec = TYPE_PRECISION (TREE_TYPE (expr));
+
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
 
@@ -1541,8 +1546,12 @@ 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)));
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (TREE_TYPE (expr)))
+    prec = GET_MODE_BITSIZE (targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (expr))));
+  else if (POINTER_TYPE_P (TREE_TYPE (expr)))
+    prec = POINTER_SIZE;
+  else
+    prec = TYPE_PRECISION (TREE_TYPE (expr));
 
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
@@ -1579,8 +1588,12 @@ 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)));
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (TREE_TYPE (expr)))
+    prec = GET_MODE_BITSIZE (targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (expr))));
+  else if (POINTER_TYPE_P (TREE_TYPE (expr)))
+    prec = POINTER_SIZE;
+  else
+    prec = TYPE_PRECISION (TREE_TYPE (expr));
 
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
@@ -4164,6 +4177,7 @@ set_type_quals (tree type, int type_qual
   TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
   TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
   TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
+  TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
 }
 
 /* Returns true iff CAND is equivalent to BASE with TYPE_QUALS.  */
@@ -4171,7 +4185,7 @@ set_type_quals (tree type, int type_qual
 bool
 check_qualified_type (const_tree cand, const_tree base, int type_quals)
 {
-  return (TYPE_QUALS (cand) == type_quals
+  return (TYPE_QUALS (CONST_CAST_TREE (cand)) == type_quals
 	  && TYPE_NAME (cand) == TYPE_NAME (base)
 	  /* Apparently this is needed for Objective-C.  */
 	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
@@ -5496,7 +5510,9 @@ build_pointer_type_for_mode (tree to_typ
 tree
 build_pointer_type (tree to_type)
 {
-  return build_pointer_type_for_mode (to_type, ptr_mode, false);
+  enum machine_mode mode = 
+    targetm.addr_space_pointer_mode (TYPE_ADDR_SPACE (strip_array_types (to_type)));
+  return build_pointer_type_for_mode (to_type, mode, false);
 }
 
 /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE.  */
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/tree.h gcc-nas/gcc/tree.h
--- gcc-clean/gcc/tree.h	2008-08-25 08:11:55.000000000 +1000
+++ gcc-nas/gcc/tree.h	2008-08-27 11:59:16.000000000 +1000
@@ -1084,6 +1084,16 @@ extern void omp_clause_range_check_faile
 #define POINTER_TYPE_P(TYPE) \
   (TREE_CODE (TYPE) == POINTER_TYPE || TREE_CODE (TYPE) == REFERENCE_TYPE)
 
+/* Nonzero if TYPE is a pointer or reference type qualified as belonging
+   to an address space that is not the generic address space.  */
+#define OTHER_ADDR_SPACE_POINTER_TYPE_P(TYPE) \
+  (POINTER_TYPE_P (TYPE) && TYPE_ADDR_SPACE (strip_array_types (TREE_TYPE (TYPE))))
+
+/* Nonzero if TYPE is a pointer or reference type, but does not belong
+   to an address space outside the generic address space.  */
+#define GENERIC_ADDR_SPACE_POINTER_TYPE_P(TYPE) \
+  (POINTER_TYPE_P (TYPE) && !TYPE_ADDR_SPACE (strip_array_types (TREE_TYPE (TYPE))))
+
 /* Nonzero if this type is a complete type.  */
 #define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
 
@@ -2173,6 +2183,9 @@ struct tree_block GTY(())
    the term.  */
 #define TYPE_RESTRICT(NODE) (TYPE_CHECK (NODE)->type.restrict_flag)
 
+/* If nonzero, this type is in the extended address space.  */
+#define TYPE_ADDR_SPACE(NODE) (TYPE_CHECK (NODE)->type.address_space)
+
 /* There is a TYPE_QUAL value for each type qualifier.  They can be
    combined by bitwise-or to form the complete set of qualifiers for a
    type.  */
@@ -2182,11 +2195,15 @@ struct tree_block GTY(())
 #define TYPE_QUAL_VOLATILE 0x2
 #define TYPE_QUAL_RESTRICT 0x4
 
+#define ENCODE_QUAL_ADDR_SPACE(NUM) ((NUM & 0xFF) << 8)
+#define DECODE_QUAL_ADDR_SPACE(X) (((X) >> 8) && 0xFF)
+
 /* The set of type qualifiers for this type.  */
 #define TYPE_QUALS(NODE)					\
   ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST)			\
    | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE)		\
-   | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT))
+   | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)		\
+   | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (strip_array_types (NODE)))))
 
 /* These flags are available for each language front end to use internally.  */
 #define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
@@ -2248,6 +2265,7 @@ struct tree_block GTY(())
   (TYPE_CHECK (NODE)->type.contains_placeholder_bits)
 
 struct die_struct;
+typedef unsigned char addr_space_t;
 
 struct tree_type GTY(())
 {
@@ -2278,7 +2296,10 @@ struct tree_type GTY(())
   unsigned lang_flag_6 : 1;
   unsigned user_align : 1;
 
+  addr_space_t address_space;
   unsigned int align;
+  alias_set_type alias_set;
+
   tree pointer_to;
   tree reference_to;
   union tree_type_symtab {
@@ -2295,7 +2316,6 @@ struct tree_type GTY(())
   tree binfo;
   tree context;
   tree canonical;
-  alias_set_type alias_set;
   /* Points to a structure whose details depend on the language in use.  */
   struct lang_type *lang_specific;
 };
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/tree-pretty-print.c gcc-nas/gcc/tree-pretty-print.c
--- gcc-clean/gcc/tree-pretty-print.c	2008-08-07 14:06:16.000000000 +1000
+++ gcc-nas/gcc/tree-pretty-print.c	2008-08-19 20:23:57.000000000 +1000
@@ -36,6 +36,8 @@ along with GCC; see the file COPYING3.  
 #include "fixed-value.h"
 #include "value-prof.h"
 #include "predict.h"
+#include "target.h"
+#include "target-def.h"
 
 /* Local functions, macros and variables.  */
 static int op_prio (const_tree);
@@ -528,6 +530,13 @@ dump_generic_node (pretty_printer *buffe
 	else if (quals & TYPE_QUAL_RESTRICT)
 	  pp_string (buffer, "restrict ");
 
+	if (TYPE_ADDR_SPACE (node))
+	  {
+	    const char *as = targetm.addr_space_name (TYPE_ADDR_SPACE (node));
+	    pp_string (buffer, as);
+	    pp_space (buffer);
+	  }
+
 	tclass = TREE_CODE_CLASS (TREE_CODE (node));
 
 	if (tclass == tcc_declaration)
@@ -604,6 +613,13 @@ dump_generic_node (pretty_printer *buffe
 	  if (quals & TYPE_QUAL_RESTRICT)
 	    pp_string (buffer, " restrict");
 
+	  if (TYPE_ADDR_SPACE (node))
+	    {
+	      const char *as = targetm.addr_space_name (TYPE_ADDR_SPACE (node));
+	      pp_string (buffer, as);
+	      pp_space (buffer);
+	    }
+	  
 	  if (TYPE_REF_CAN_ALIAS_ALL (node))
 	    pp_string (buffer, " {ref-all}");
 	}
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/tree-ssa.c gcc-nas/gcc/tree-ssa.c
--- gcc-clean/gcc/tree-ssa.c	2008-08-21 13:08:27.000000000 +1000
+++ gcc-nas/gcc/tree-ssa.c	2008-08-27 12:04:16.000000000 +1000
@@ -1118,6 +1118,12 @@ useless_type_conversion_p_1 (tree outer_
 	  && TYPE_VOLATILE (TREE_TYPE (outer_type)))
 	return false;
 
+      /* Do not lose casts between pointers in different address
+	 spaces.  */
+      if (TYPE_ADDR_SPACE (TREE_TYPE (inner_type))
+	  != TYPE_ADDR_SPACE (TREE_TYPE (outer_type)))
+	return false;
+
       /* Do not lose casts between pointers with different
 	 TYPE_REF_CAN_ALIAS_ALL setting or alias sets.  */
       if ((TYPE_REF_CAN_ALIAS_ALL (inner_type)
@@ -1209,8 +1215,8 @@ useless_type_conversion_p (tree outer_ty
   /* If the outer type is (void *), then the conversion is not
      necessary.  We have to make sure to not apply this while
      recursing though.  */
-  if (POINTER_TYPE_P (inner_type)
-      && POINTER_TYPE_P (outer_type)
+  if (GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type)
+      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (outer_type)
       && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
     return true;
 
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/tree-ssa-loop-ivopts.c gcc-nas/gcc/tree-ssa-loop-ivopts.c
--- gcc-clean/gcc/tree-ssa-loop-ivopts.c	2008-08-05 08:57:25.000000000 +1000
+++ gcc-nas/gcc/tree-ssa-loop-ivopts.c	2008-08-05 23:36:33.000000000 +1000
@@ -2011,9 +2011,16 @@ strip_offset (tree expr, unsigned HOST_W
 static tree
 generic_type_for (tree type)
 {
-  if (POINTER_TYPE_P (type))
+  if (GENERIC_ADDR_SPACE_POINTER_TYPE_P (type))
     return unsigned_type_for (type);
 
+  if (OTHER_ADDR_SPACE_POINTER_TYPE_P (type))
+    {
+      int qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (TREE_TYPE (type)));
+      return build_pointer_type
+	(build_qualified_type (void_type_node, qual));
+    }
+
   if (TYPE_UNSIGNED (type))
     return type;
 
diff -N -p --exclude=spu --exclude=config/spu --exclude=ea --exclude=LAST_UPDATED --exclude=REVISION --exclude=ChangeLog --exclude=ChangeLog.named -r -u --exclude=.svn gcc-clean/gcc/varasm.c gcc-nas/gcc/varasm.c
--- gcc-clean/gcc/varasm.c	2008-08-21 06:42:08.000000000 +1000
+++ gcc-nas/gcc/varasm.c	2008-08-28 16:35:19.000000000 +1000
@@ -1284,6 +1284,7 @@ make_decl_rtl (tree decl)
   const char *name = 0;
   int reg_number;
   rtx x;
+  enum machine_mode addrmode;
 
   /* Check that we are not being given an automatic variable.  */
   gcc_assert (TREE_CODE (decl) != PARM_DECL
@@ -1428,7 +1429,13 @@ 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);
+    {
+      addrmode = (TREE_TYPE (decl) == error_mark_node)
+	? Pmode
+	: targetm.addr_space_pointer_mode
+	(TYPE_ADDR_SPACE (TREE_TYPE (decl)));
+      x = gen_rtx_SYMBOL_REF (addrmode, name);
+    }
   SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
   SET_SYMBOL_REF_DECL (x, decl);
 
@@ -6283,6 +6290,15 @@ default_valid_pointer_mode (enum machine
   return (mode == ptr_mode || mode == Pmode);
 }
 
+/* Return the pointer mode for a given ADDRSPACE, defaulting to
+   ptr_mode for the generic address space only.  */
+enum machine_mode
+default_addr_space_pointer_mode (int addrspace)
+{
+  gcc_assert (addrspace == 0);
+  return ptr_mode;
+}
+
 /* 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.  */

-------------- next part --------------
A non-text attachment was scrubbed...
Name: cast1.c
Type: text/x-csrc
Size: 388 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080830/f8ecf8cf/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: compile.c
Type: text/x-csrc
Size: 1277 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080830/f8ecf8cf/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cppdefine32.c
Type: text/x-csrc
Size: 182 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080830/f8ecf8cf/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cppdefine64.c
Type: text/x-csrc
Size: 128 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080830/f8ecf8cf/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: errors.c
Type: text/x-csrc
Size: 1681 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080830/f8ecf8cf/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: options1.c
Type: text/x-csrc
Size: 98 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080830/f8ecf8cf/attachment-0005.bin>


More information about the Gcc-patches mailing list