public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: named address space support (1/2: target-independent parts)
@ 2008-08-20  7:29 Ben Elliston
  2008-08-20 10:36 ` Richard Guenther
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-20  7:29 UTC (permalink / raw)
  To: gcc-patches

This patch introduces all of the target-independent code from the
named-addr-spaces-branch into mainline.  It implements a sensible subset
of the named address space functionality described in:

  http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf

The current state of the implementation is:

  - a target can define any number of address spaces;

  - the target defines how pointers are transformed when
    cast to/from the generic address space;

  - casts between two non-generic address spaces is not yet
    implemented, but there is nothing about the implementation
    that would prevent this from being added at a later
    stage.

I will post a follow-up patch that brings across the SPU backend
changes.

This code has been in use in the Cell SDK compiler for some time, so is
quite well exercised already.  This patch has been tested with a
bootstrap on x86_64-linux and powerpc-linux, regression tested on
spu-elf (no regressions), and doco changes were tested by "make info
dvi" and visual inspection.

Okay for mainline?

Thanks, Ben



--- gcc-clean/gcc/c-decl.c	2008-08-14 13:27:13.000000000 +1000
+++ gcc-nas/gcc/c-decl.c	2008-08-20 11:50:29.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.  */
@@ -2898,7 +2899,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 (0, "empty declaration with type qualifier "
@@ -2967,7 +2969,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;
@@ -2990,7 +2993,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
@@ -3949,6 +3953,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;
@@ -4063,6 +4068,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)
@@ -4071,12 +4077,15 @@ grokdeclarator (const struct c_declarato
 	pedwarn (OPT_pedantic, "duplicate %<restrict%>");
       if (volatilep > 1)
 	pedwarn (OPT_pedantic, "duplicate %<volatile%>");
+      if (addr_space_p > 1)
+	pedwarn (OPT_pedantic, "duplicate %qs", targetm.addr_space_name (TYPE_ADDR_SPACE (element_type)));
     }
   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.).  */
@@ -4102,6 +4111,56 @@ grokdeclarator (const struct c_declarato
 	  || storage_class == csc_typedef)
 	storage_class = csc_none;
     }
+  else if (declspecs->address_space)
+    {
+      const char *addrspace_name;
+
+      /* Does the target have named address spaces?  */
+      if (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;
+	}
+
+      addrspace_name = targetm.addr_space_name (declspecs->address_space);
+      if (decl_context == NORMAL)
+	{
+	  if (declarator->kind == cdk_function)
+	    error ("%qs specified for function %qs", addrspace_name, name);
+	  else if (declarator->kind == cdk_id)
+	    {
+
+	      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_static:
+		  error ("%qs combined with %<static%> qualifier for %qs", addrspace_name, name);
+		  break;
+		case csc_none:
+		  if (current_function_scope)
+		    error ("%qs specified for auto variable %qs", addrspace_name, name);
+		  else
+		    error ("%qs variable %qs must be extern", addrspace_name, name);
+		  break;
+		case csc_extern:
+		  /* fall through */
+		case csc_typedef:
+		  break;
+		}
+	    }
+	}
+      else if (decl_context == PARM && declarator->kind == cdk_id)
+	error ("%qs specified for parameter %qs", addrspace_name, name);
+      else if (decl_context == FIELD)
+	error ("%qs specified for structure field %qs", addrspace_name, name);
+    }
   else if (decl_context != NORMAL && (storage_class != csc_none || threadp))
     {
       if (decl_context == PARM && storage_class == csc_register)
@@ -4846,6 +4905,10 @@ grokdeclarator (const struct c_declarato
 
 	type = c_build_qualified_type (type, type_quals);
 
+	if (POINTER_TYPE_P (type) && TYPE_ADDR_SPACE (type) && !extern_ref)
+	  error ("%qs variable %qs must be extern", 
+		 targetm.addr_space_name (TYPE_ADDR_SPACE (type)), name);
+
 	/* C99 6.2.2p7: It is invalid (compile-time undefined
 	   behavior) to create an 'extern' declaration for a
 	   variable if there is a global declaration that is
@@ -7085,9 +7148,23 @@ build_null_declspecs (void)
   ret->volatile_p = false;
   ret->restrict_p = false;
   ret->saturating_p = false;
+  ret->address_space = 0;
   return ret;
 }
 
+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)
+    pedwarn (OPT_pedantic, "duplicate %qs", 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.  */
 
--- gcc-clean/gcc/c-objc-common.c	2008-04-03 15:14:25.000000000 +1100
+++ gcc-nas/gcc/c-objc-common.c	2008-06-16 16:22:24.000000000 +1000
@@ -187,6 +187,9 @@ c_initialize_diagnostics (diagnostic_con
 int
 c_types_compatible_p (tree x, tree y)
 {
+  if (TYPE_ADDR_SPACE (x) != TYPE_ADDR_SPACE (y))
+    return false;
+
   return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
 }
 
--- gcc-clean/gcc/c-parser.c	2008-08-18 22:11:04.000000000 +1000
+++ gcc-nas/gcc/c-parser.c	2008-08-20 11:50:29.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:
@@ -1393,6 +1404,7 @@ c_parser_asm_definition (c_parser *parse
      const
      restrict
      volatile
+     address-space-qualifier
 
    (restrict is new in C99.)
 
@@ -1401,6 +1413,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
 
@@ -1440,6 +1458,16 @@ 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 && !c_dialect_objc ())
+	    {
+	      declspecs_add_addrspace (specs, c_parser_peek_token (parser)->value);
+	      c_parser_consume_token (parser);
+	      attrs_ok = true;
+	      seen_type = 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.  */
@@ -5506,6 +5534,12 @@ c_parser_postfix_expression_after_paren_
   finish_init ();
   maybe_warn_string_init (type, init);
 
+  if (type != error_mark_node && TYPE_ADDR_SPACE (type) && current_function_decl)
+    {
+      error ("compound literal qualified by address-space qualifier");
+      type = error_mark_node;
+    }
+
   if (!flag_isoc99)
     pedwarn (OPT_pedantic, "%HISO C90 forbids compound literals", 
 	     &start_loc);
--- 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:
--- gcc-clean/gcc/c-tree.h	2008-08-14 13:27:13.000000000 +1000
+++ gcc-nas/gcc/c-tree.h	2008-08-20 11:50:29.000000000 +1000
@@ -286,6 +286,8 @@ struct c_declspecs {
   BOOL_BITFIELD restrict_p : 1;
   /* Whether "_Sat" was specified.  */
   BOOL_BITFIELD saturating_p : 1;
+  /* Whether the declaration is in another address space.  */
+  unsigned char 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 */
--- gcc-clean/gcc/c-typeck.c	2008-08-11 09:37:45.000000000 +1000
+++ gcc-nas/gcc/c-typeck.c	2008-08-19 20:18:46.000000000 +1000
@@ -8180,6 +8180,16 @@ build_binary_op (enum tree_code code, tr
 		  && TREE_CODE (tt1) == FUNCTION_TYPE)
 		pedwarn (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))
 	    {
@@ -8187,6 +8197,16 @@ build_binary_op (enum tree_code code, tr
 		  && TREE_CODE (tt0) == FUNCTION_TYPE)
 		pedwarn (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.  */
--- gcc-clean/gcc/convert.c	2008-05-11 14:37:53.000000000 +1000
+++ gcc-nas/gcc/convert.c	2008-06-16 16:22:24.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 (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:
--- gcc-clean/gcc/dwarf2out.c	2008-08-14 13:27:13.000000000 +1000
+++ gcc-nas/gcc/dwarf2out.c	2008-08-19 20:16:13.000000000 +1000
@@ -9505,6 +9505,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 (item_type))
+	add_AT_unsigned (mod_type_die, DW_AT_address_class,
+			 TYPE_ADDR_SPACE (item_type));
     }
   else if (code == REFERENCE_TYPE)
     {
@@ -9512,6 +9515,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 (item_type))
+	add_AT_unsigned (mod_type_die, DW_AT_address_class,
+			 TYPE_ADDR_SPACE (item_type));
     }
   else if (is_subrange_type (type))
     {
--- gcc-clean/gcc/emit-rtl.c	2008-07-31 13:23:06.000000000 +1000
+++ gcc-nas/gcc/emit-rtl.c	2008-07-31 13:41:57.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);
+				 unsigned char, 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, unsigned char 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,7 @@ 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 (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 +1777,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 +1791,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, unsigned char 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 +1822,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 +1831,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 +1841,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));
 }
 \f
@@ -1898,7 +1909,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 +1976,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 +2035,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 +2139,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;
 }
--- 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);
 
--- 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);
     }
--- 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,
--- gcc-clean/gcc/fold-const.c	2008-08-19 06:55:43.000000000 +1000
+++ gcc-nas/gcc/fold-const.c	2008-08-19 20:14:19.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)
--- 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 *);
--- 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;
 
--- gcc-clean/gcc/rtl.h	2008-07-31 13:23:06.000000000 +1000
+++ gcc-nas/gcc/rtl.h	2008-08-20 10:32:01.000000000 +1000
@@ -146,6 +146,7 @@ typedef struct mem_attrs GTY(())
   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)							\
--- gcc-clean/gcc/target-def.h	2008-07-31 13:23:06.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,			\
--- gcc-clean/gcc/target.h	2008-07-31 13:23:05.000000000 +1000
+++ gcc-nas/gcc/target.h	2008-07-31 13:40:36.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.  */
--- gcc-clean/gcc/targhooks.h	2008-07-24 13:24:12.000000000 +1000
+++ gcc-nas/gcc/targhooks.h	2008-07-24 13:49:34.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);
--- gcc-clean/gcc/targhooks.c	2008-07-24 13:24:12.000000000 +1000
+++ gcc-nas/gcc/targhooks.c	2008-07-24 13:43:29.000000000 +1000
@@ -703,6 +703,22 @@ default_builtin_vector_alignment_reachab
   return true;
 }
 
+const char *
+default_addr_space_name (int addrspace ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
+rtx (* default_addr_space_conversion_rtl (int from ATTRIBUTE_UNUSED, int to ATTRIBUTE_UNUSED)) (rtx, rtx)
+{
+  gcc_unreachable ();
+}
+
+unsigned char default_addr_space_number (const tree ident ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
 bool
 default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
 {
--- 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}");
 	}
--- 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;
 
--- gcc-clean/gcc/tree-ssa.c	2008-08-11 09:37:45.000000000 +1000
+++ gcc-nas/gcc/tree-ssa.c	2008-08-19 20:19:06.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)
@@ -1211,7 +1217,9 @@ useless_type_conversion_p (tree outer_ty
      recursing though.  */
   if (POINTER_TYPE_P (inner_type)
       && POINTER_TYPE_P (outer_type)
-      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
+      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE
+      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type)
+      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (outer_type))
     return true;
 
   return useless_type_conversion_p_1 (outer_type, inner_type);
--- gcc-clean/gcc/tree.c	2008-08-20 09:32:13.000000000 +1000
+++ gcc-nas/gcc/tree.c	2008-08-19 20:14:04.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);
@@ -4130,6 +4143,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.  */
@@ -5462,7 +5476,8 @@ 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 (to_type));
+  return build_pointer_type_for_mode (to_type, mode, false);
 }
 
 /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE.  */
@@ -8819,9 +8834,7 @@ block_nonartificial_location (tree block
     {
       tree ao = BLOCK_ABSTRACT_ORIGIN (block);
 
-      while (TREE_CODE (ao) == BLOCK
-	     && BLOCK_ABSTRACT_ORIGIN (ao)
-	     && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
+      while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
 	ao = BLOCK_ABSTRACT_ORIGIN (ao);
 
       if (TREE_CODE (ao) == FUNCTION_DECL)
--- gcc-clean/gcc/tree.h	2008-08-19 06:55:43.000000000 +1000
+++ gcc-nas/gcc/tree.h	2008-08-20 10:45:59.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 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 (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 (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 (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)
@@ -2279,6 +2296,8 @@ struct tree_type GTY(())
   unsigned user_align : 1;
 
   unsigned int align;
+  unsigned char address_space;
+
   tree pointer_to;
   tree reference_to;
   union tree_type_symtab {
--- gcc-clean/gcc/varasm.c	2008-08-20 09:32:13.000000000 +1000
+++ gcc-nas/gcc/varasm.c	2008-08-06 21:21:55.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,10 @@ 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);
 
@@ -2286,10 +2290,6 @@ process_pending_assemble_externals (void
 #endif
 }
 
-/* This TREE_LIST contains any weak symbol declarations waiting
-   to be emitted.  */
-static GTY(()) tree weak_decls;
-
 /* Output something to declare an external symbol to the assembler.
    (Most assemblers don't need this, so we normally output nothing.)
    Do nothing if DECL is not external.  */
@@ -2307,9 +2307,6 @@ assemble_external (tree decl ATTRIBUTE_U
   if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
     return;
 
-  if (SUPPORTS_WEAK && DECL_WEAK (decl))
-    weak_decls = tree_cons (NULL, decl, weak_decls);
-
   /* We want to output external symbols at very last to check if they
      are references or not.  */
   pending_assemble_externals = tree_cons (0, decl,
@@ -4853,6 +4850,10 @@ output_constructor (tree exp, unsigned H
     assemble_zeros (size - total_bytes);
 }
 
+/* This TREE_LIST contains any weak symbol declarations waiting
+   to be emitted.  */
+static GTY(()) tree weak_decls;
+
 /* Mark DECL as weak.  */
 
 static void
@@ -4945,7 +4946,12 @@ declare_weak (tree decl)
     error ("weak declaration of %q+D must be public", decl);
   else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
     error ("weak declaration of %q+D must precede definition", decl);
-  else if (!SUPPORTS_WEAK)
+  else if (SUPPORTS_WEAK)
+    {
+      if (! DECL_WEAK (decl))
+	weak_decls = tree_cons (NULL, decl, weak_decls);
+    }
+  else
     warning (0, "weak declaration of %q+D not supported", decl);
 
   mark_weak (decl);
@@ -6283,6 +6289,13 @@ default_valid_pointer_mode (enum machine
   return (mode == ptr_mode || mode == Pmode);
 }
 
+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.  */
--- gcc-clean/gcc/doc/extend.texi	2008-08-18 22:11:01.000000000 +1000
+++ gcc-nas/gcc/doc/extend.texi	2008-08-19 20:13:38.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 N1169 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 @var{__ea} address space identifier:
+
+@smallexample
+extern int __ea i;
+@end smallexample
+
+When the variable @var{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 @var{__ea} identifier may be used exactly like any other C type
+qualifier (e.g. const or volatile).  See the N1169 document for more
+details.
+
 @node Zero Length
 @section Arrays of Length Zero
 @cindex arrays of length zero
--- 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
--- gcc-clean/gcc/doc/tm.texi	2008-08-17 09:48:09.000000000 +1000
+++ gcc-nas/gcc/doc/tm.texi	2008-08-20 12:28:17.000000000 +1000
@@ -4170,10 +4170,9 @@ hook returns true for both @code{ptr_mod
 @end deftypefn
 
 @deftypefn {Target Hook} bool TARGET_SCALAR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
-Define this to return nonzero if the port is prepared to handle
-insns involving scalar mode @var{mode}.  For a scalar mode to be
-considered supported, all the basic arithmetic and comparisons
-must work.
+Define this to return nonzero if the port is prepared to handle insns
+involving scalar mode @var{mode}.  For a scalar mode to be considered
+supported, all the basic arithmetic and comparisons must work.
 
 The default version of this hook returns true for any mode
 required to handle the basic C types (as defined by the port).
@@ -10550,3 +10549,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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent parts)
  2008-08-20  7:29 PATCH: named address space support (1/2: target-independent parts) Ben Elliston
@ 2008-08-20 10:36 ` Richard Guenther
  2008-08-20 12:00   ` Ben Elliston
  2008-08-21  6:03   ` PATCH: named address space support (1/2: target-independent parts) Ben Elliston
  2008-08-20 12:11 ` Joseph S. Myers
  2008-08-20 19:49 ` Joseph S. Myers
  2 siblings, 2 replies; 18+ messages in thread
From: Richard Guenther @ 2008-08-20 10:36 UTC (permalink / raw)
  To: Ben Elliston; +Cc: gcc-patches

On Wed, Aug 20, 2008 at 7:50 AM, Ben Elliston <bje@au1.ibm.com> wrote:
> This patch introduces all of the target-independent code from the
> named-addr-spaces-branch into mainline.  It implements a sensible subset
> of the named address space functionality described in:
>
>  http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf
>
> The current state of the implementation is:
>
>  - a target can define any number of address spaces;
>
>  - the target defines how pointers are transformed when
>    cast to/from the generic address space;
>
>  - casts between two non-generic address spaces is not yet
>    implemented, but there is nothing about the implementation
>    that would prevent this from being added at a later
>    stage.
>
> I will post a follow-up patch that brings across the SPU backend
> changes.
>
> This code has been in use in the Cell SDK compiler for some time, so is
> quite well exercised already.  This patch has been tested with a
> bootstrap on x86_64-linux and powerpc-linux, regression tested on
> spu-elf (no regressions), and doco changes were tested by "make info
> dvi" and visual inspection.
>
> Okay for mainline?

There are several new functions in the patch without a comment.

  BOOL_BITFIELD saturating_p : 1;
+  /* Whether the declaration is in another address space.  */
+  unsigned char address_space;
 };

"Whether" looks incorrect.

@@ -2279,6 +2296,8 @@ struct tree_type GTY(())
  unsigned user_align : 1;

  unsigned int align;
+  unsigned char address_space;
+
  tree pointer_to;
  tree reference_to;
  union tree_type_symtab {

please re-order fields to not increase the size of tree_type too much.
Move the alias_set member next to the align member and add the
address_space member before align to allow packing with the
bitfields if we ever decide to allocate more of them.

@@ -146,6 +146,7 @@ typedef struct mem_attrs GTY(())
  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;

likewise, please move the align member next to the alias_set member
while you are at it.

@@ -1211,7 +1217,9 @@ useless_type_conversion_p (tree outer_ty
     recursing though.  */
  if (POINTER_TYPE_P (inner_type)
      && POINTER_TYPE_P (outer_type)
-      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
+      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE
+      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type)
+      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (outer_type))
    return true;

in other places you simply replaced POINTER_TYPE_P with
GENERIC_ADDR_SPACE_POINTER_TYPE_P - why is this not
correct here?

As a general remark, instead of using 'unsigned char' for the
address-space number I would have prefered that you introduce
a typedef somewhere.

The middle-end parts look ok, though I think the majority of the
patch should be reviewed by a C frontend maintainer.  Out of
curiosity, does GNU C++ after this patch support named
address-spaces?

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20 10:36 ` Richard Guenther
@ 2008-08-20 12:00   ` Ben Elliston
  2008-08-20 12:47     ` C++ support? Re: PATCH: named address space support Ulrich Weigand
  2008-08-21  6:03   ` PATCH: named address space support (1/2: target-independent parts) Ben Elliston
  1 sibling, 1 reply; 18+ messages in thread
From: Ben Elliston @ 2008-08-20 12:00 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

Hi Richard

> There are several new functions in the patch without a comment.

OK; I will double check them all.

>   BOOL_BITFIELD saturating_p : 1;
> +  /* Whether the declaration is in another address space.  */
> +  unsigned char address_space;
>  };
> 
> "Whether" looks incorrect.

True enough :-)

> As a general remark, instead of using 'unsigned char' for the
> address-space number I would have prefered that you introduce
> a typedef somewhere.

Yep, that was bothering me, but I thought I'd just get the patch out and
see.  I will indeed fix that.

> The middle-end parts look ok, though I think the majority of the
> patch should be reviewed by a C frontend maintainer.  Out of
> curiosity, does GNU C++ after this patch support named
> address-spaces?

No.  The embedded C proposal does not cover C++ and the patch does not
enable this feature in the C++ front-end.  That may change in future,
but the language interactions of any proposed extension need to be
carefully thought through.

Thanks for the review!

Cheers, Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20  7:29 PATCH: named address space support (1/2: target-independent parts) Ben Elliston
  2008-08-20 10:36 ` Richard Guenther
@ 2008-08-20 12:11 ` Joseph S. Myers
  2008-08-21  8:37   ` Ben Elliston
  2008-08-20 19:49 ` Joseph S. Myers
  2 siblings, 1 reply; 18+ messages in thread
From: Joseph S. Myers @ 2008-08-20 12:11 UTC (permalink / raw)
  To: Ben Elliston; +Cc: gcc-patches

On Wed, 20 Aug 2008, Ben Elliston wrote:

> This patch introduces all of the target-independent code from the
> named-addr-spaces-branch into mainline.  It implements a sensible subset
> of the named address space functionality described in:
> 
>   http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf

I'll look at the patch later, but could you confirm whether any of the 
changes in N1275, which I believe to be the latest draft of TR 18037, 
affect this feature?  (Although at least one version has been published as 
a TR, for TRs we don't try to support the differences between successive 
revisions under options to select different versions; we only do that for 
major revisions of the actual standard; so if N1275 changes are relevant 
then they are what could be implemented.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* C++ support? Re: PATCH: named address space support
  2008-08-20 12:00   ` Ben Elliston
@ 2008-08-20 12:47     ` Ulrich Weigand
  2008-08-20 14:05       ` Ben Elliston
  0 siblings, 1 reply; 18+ messages in thread
From: Ulrich Weigand @ 2008-08-20 12:47 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Guenther, bje

Ben Elliston wrote:

> > The middle-end parts look ok, though I think the majority of the
> > patch should be reviewed by a C frontend maintainer.  Out of
> > curiosity, does GNU C++ after this patch support named
> > address-spaces?
> 
> No.  The embedded C proposal does not cover C++ and the patch does not
> enable this feature in the C++ front-end.  That may change in future,
> but the language interactions of any proposed extension need to be
> carefully thought through.

In fact, we'd be pretty interested in a C++ extension of this feature;
unfortunately, there doesn't seem to exist an already worked-out 
definition of language extension syntax/semantics for named address
spaces for C++ equivalent to the C version in TR 18037.

If any of the C++ experts has some advice or pointers to how this 
feature should be implemented in C++, we'd much appreciate that!

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: C++ support? Re: PATCH: named address space support
  2008-08-20 12:47     ` C++ support? Re: PATCH: named address space support Ulrich Weigand
@ 2008-08-20 14:05       ` Ben Elliston
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-20 14:05 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches, Richard Guenther

> In fact, we'd be pretty interested in a C++ extension of this feature;
> unfortunately, there doesn't seem to exist an already worked-out 
> definition of language extension syntax/semantics for named address
> spaces for C++ equivalent to the C version in TR 18037.

Based on previous experience with C extensions (namely DFP), my guess is
that the C++ standards committee would like to see this implemented in
the standard library (for example, as a templated type).  Something like
`__ea<int *> i'?

Ben


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20  7:29 PATCH: named address space support (1/2: target-independent parts) Ben Elliston
  2008-08-20 10:36 ` Richard Guenther
  2008-08-20 12:11 ` Joseph S. Myers
@ 2008-08-20 19:49 ` Joseph S. Myers
  2008-08-20 20:49   ` Ben Elliston
                     ` (2 more replies)
  2 siblings, 3 replies; 18+ messages in thread
From: Joseph S. Myers @ 2008-08-20 19:49 UTC (permalink / raw)
  To: Ben Elliston; +Cc: gcc-patches

On Wed, 20 Aug 2008, Ben Elliston wrote:

> I will post a follow-up patch that brings across the SPU backend
> changes.

This will be needed in order to review this first patch properly, as a 
requirement for review will be an adequate set of testcases, and those 
will I think necessarily be target-specific.

> @@ -4071,12 +4077,15 @@ grokdeclarator (const struct c_declarato
>  	pedwarn (OPT_pedantic, "duplicate %<restrict%>");
>        if (volatilep > 1)
>  	pedwarn (OPT_pedantic, "duplicate %<volatile%>");
> +      if (addr_space_p > 1)
> +	pedwarn (OPT_pedantic, "duplicate %qs", targetm.addr_space_name (TYPE_ADDR_SPACE (element_type)));

I don't think this is appropriate.  This is a pedwarn in the pedantic 
non-C99 case only, for duplicate qualifiers via typedef (direct duplicates 
are handled elsewhere).  The TR certainly does not consider pre-C99.  The 
correct checks are:

* If there are "qualifiers for two or more different address spaces", 
whether via typedefs or directly, give an error.

* For duplicates of the same qualifier, whether via typedefs or directly, 
allow them quietly.

with testcases for both of those (though if you don't have multiple named 
address spaces for any target at present, you won't be able to test the 
first).

> +		case csc_static:
> +		  error ("%qs combined with %<static%> qualifier for %qs", addrspace_name, name);
> +		  break;

Why are you disallowing address spaces together with static?  As far as I 
can tell the TR allows them.

Where do you check the constraint that a function type is not qualified 
with an address space qualifier?

> @@ -4846,6 +4905,10 @@ grokdeclarator (const struct c_declarato
>  
>  	type = c_build_qualified_type (type, type_quals);
>  
> +	if (POINTER_TYPE_P (type) && TYPE_ADDR_SPACE (type) && !extern_ref)
> +	  error ("%qs variable %qs must be extern", 
> +		 targetm.addr_space_name (TYPE_ADDR_SPACE (type)), name);

I don't see why such a check should be conditional on the type being a 
pointer type, and again I think initialized declarations and static 
declarations are valid.

> +  if (specs->address_space > 0)
> +    pedwarn (OPT_pedantic, "duplicate %qs", targetm.addr_space_name (specs->address_space));

The same point about duplicates as above applies: if a different address 
space then give an error, otherwise it is valid and so should not receive 
a pedwarn.

> +	  if (kind == C_ID_ADDRSPACE && !c_dialect_objc ())

Why the c_dialect_objc check?  If the feature is to be unsupported for 
Objective-C, a proper error in that case is needed.

> +	    {
> +	      declspecs_add_addrspace (specs, c_parser_peek_token (parser)->value);
> +	      c_parser_consume_token (parser);
> +	      attrs_ok = true;
> +	      seen_type = true;

I don't think setting seen_type here is correct; these are like qualifiers 
and qualifiers don't set seen_type.  The relevant testcase (that should go 
in the testsuite) would be an address-space qualifier followed by a 
typedef-name that was declared in an outer scope; without seen_type set 
the typedef-name will be handled as such, with seen_type set it will be 
treated as an identifier being redeclared in this scope as a variable.

> +	      /* 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));
> +		}

For both places comparison operators are handled, the relevant check is 
not whether an address space is other than generic, it is whether the 
address spaces overlap.  If not, an error must be given.  If they do 
overlap, both must be converted to whichever is the larger address space 
(not whichever is the smaller).

Conditional expressions need similar handling.

I don't see any changes to convert_for_assignment to check the constraints 
on pointer assignment (and argument passing, function return, 
initialization) and address spaces.

> +@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 N1169 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 @var{__ea} address space identifier:

@var is for metasyntactic variables, not for programming language text 
(including names of programming language variables).  You mean 
@code{__ea}.

> +When the variable @var{i} is accessed, the compiler will generate

@code{i}.  And you need to define quite what the qualifier means, possibly 
with reference to an external SPU specification.

> +The @var{__ea} identifier may be used exactly like any other C type

@code{__ea}.

> +qualifier (e.g. const or volatile).  See the N1169 document for more

"e.g." needs to be followed by a comma or by "@:".  @code{const}, 
@code{volatile}.

>  @deftypefn {Target Hook} bool TARGET_SCALAR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
> -Define this to return nonzero if the port is prepared to handle
> -insns involving scalar mode @var{mode}.  For a scalar mode to be
> -considered supported, all the basic arithmetic and comparisons
> -must work.
> +Define this to return nonzero if the port is prepared to handle insns
> +involving scalar mode @var{mode}.  For a scalar mode to be considered
> +supported, all the basic arithmetic and comparisons must work.

Don't mix reformatting this paragraph in with substantive unrelated 
changes to the compiler.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20 19:49 ` Joseph S. Myers
@ 2008-08-20 20:49   ` Ben Elliston
  2008-08-28 21:30   ` Ben Elliston
  2008-08-30 13:05   ` *revised* " Ben Elliston
  2 siblings, 0 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-20 20:49 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

Hi Joseph

Thanks for the review.  I've just dealt with all of the suggested
documentation changes (the easy bit) :-)

> @var is for metasyntactic variables, not for programming language text 
> (including names of programming language variables).  You mean 
> @code{__ea}.

OK.

> > +The @var{__ea} identifier may be used exactly like any other C type
> 
> @code{__ea}.

Fixed.

> > +qualifier (e.g. const or volatile).  See the N1169 document for more
> 
> "e.g." needs to be followed by a comma or by "@:".  @code{const}, 
> @code{volatile}.

Fixed.

> >  @deftypefn {Target Hook} bool TARGET_SCALAR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
> > -Define this to return nonzero if the port is prepared to handle
> > -insns involving scalar mode @var{mode}.  For a scalar mode to be
> > -considered supported, all the basic arithmetic and comparisons
> > -must work.
> > +Define this to return nonzero if the port is prepared to handle insns
> > +involving scalar mode @var{mode}.  For a scalar mode to be considered
> > +supported, all the basic arithmetic and comparisons must work.
> 
> Don't mix reformatting this paragraph in with substantive unrelated 
> changes to the compiler.

This was an unitended paragraph fill in emacs.  I've reverted that hunk.

Cheers, Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20 10:36 ` Richard Guenther
  2008-08-20 12:00   ` Ben Elliston
@ 2008-08-21  6:03   ` Ben Elliston
  2008-08-21 10:51     ` Richard Guenther
  1 sibling, 1 reply; 18+ messages in thread
From: Ben Elliston @ 2008-08-21  6:03 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

Hi Richard

I've applied your suggestions, thanks.

> There are several new functions in the patch without a comment.

You don't say which ones, but I think I've got them all.

>   BOOL_BITFIELD saturating_p : 1;
> +  /* Whether the declaration is in another address space.  */
> +  unsigned char address_space;
>  };
> 
> "Whether" looks incorrect.

Fixed.

> @@ -2279,6 +2296,8 @@ struct tree_type GTY(())
>   unsigned user_align : 1;
> 
>   unsigned int align;
> +  unsigned char address_space;
> +
>   tree pointer_to;
>   tree reference_to;
>   union tree_type_symtab {
> 
> please re-order fields to not increase the size of tree_type too much.
> Move the alias_set member next to the align member and add the
> address_space member before align to allow packing with the
> bitfields if we ever decide to allocate more of them.

Fixed.

> @@ -146,6 +146,7 @@ typedef struct mem_attrs GTY(())
>   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;
> 
> likewise, please move the align member next to the alias_set member
> while you are at it.

Fixed.

> @@ -1211,7 +1217,9 @@ useless_type_conversion_p (tree outer_ty
>      recursing though.  */
>   if (POINTER_TYPE_P (inner_type)
>       && POINTER_TYPE_P (outer_type)
> -      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
> +      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE
> +      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type)
> +      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (outer_type))
>     return true;
> 
> in other places you simply replaced POINTER_TYPE_P with
> GENERIC_ADDR_SPACE_POINTER_TYPE_P - why is this not
> correct here?

Because previously, useless_type_conversion_p would eliminate casts
between a void * and a pointer to any type.  Such casts cannot be
eliminated when casting (for example) between a pointer in another
address space and a void * in the generic address space, as some
computation must be done to translate the address.  Yes, this is a
special case as far as useless_type_conversion_p is concerned.

Happy to leave this alone?

> As a general remark, instead of using 'unsigned char' for the
> address-space number I would have prefered that you introduce
> a typedef somewhere.

Fixed.

I will post a revised patch once I address Joseph's comments.

Cheers, Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20 12:11 ` Joseph S. Myers
@ 2008-08-21  8:37   ` Ben Elliston
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-21  8:37 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

> I'll look at the patch later, but could you confirm whether any of the 
> changes in N1275, which I believe to be the latest draft of TR 18037, 
> affect this feature?  (Although at least one version has been published as 
> a TR, for TRs we don't try to support the differences between successive 
> revisions under options to select different versions; we only do that for 
> major revisions of the actual standard; so if N1275 changes are relevant 
> then they are what could be implemented.)

I see nothing in N1275 that looks different to N1169 in this regard.  I
will update any references to N1169 in my patch, however.

Cheers, Ben

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent parts)
  2008-08-21  6:03   ` PATCH: named address space support (1/2: target-independent parts) Ben Elliston
@ 2008-08-21 10:51     ` Richard Guenther
  2008-08-21 11:25       ` Ben Elliston
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Guenther @ 2008-08-21 10:51 UTC (permalink / raw)
  To: Ben Elliston; +Cc: gcc-patches

On Thu, Aug 21, 2008 at 6:04 AM, Ben Elliston <bje@au1.ibm.com> wrote:
> Hi Richard
>
> I've applied your suggestions, thanks.
>
>> There are several new functions in the patch without a comment.
>
> You don't say which ones, but I think I've got them all.
>
>>   BOOL_BITFIELD saturating_p : 1;
>> +  /* Whether the declaration is in another address space.  */
>> +  unsigned char address_space;
>>  };
>>
>> "Whether" looks incorrect.
>
> Fixed.
>
>> @@ -2279,6 +2296,8 @@ struct tree_type GTY(())
>>   unsigned user_align : 1;
>>
>>   unsigned int align;
>> +  unsigned char address_space;
>> +
>>   tree pointer_to;
>>   tree reference_to;
>>   union tree_type_symtab {
>>
>> please re-order fields to not increase the size of tree_type too much.
>> Move the alias_set member next to the align member and add the
>> address_space member before align to allow packing with the
>> bitfields if we ever decide to allocate more of them.
>
> Fixed.
>
>> @@ -146,6 +146,7 @@ typedef struct mem_attrs GTY(())
>>   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;
>>
>> likewise, please move the align member next to the alias_set member
>> while you are at it.
>
> Fixed.
>
>> @@ -1211,7 +1217,9 @@ useless_type_conversion_p (tree outer_ty
>>      recursing though.  */
>>   if (POINTER_TYPE_P (inner_type)
>>       && POINTER_TYPE_P (outer_type)
>> -      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
>> +      && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE
>> +      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type)
>> +      && GENERIC_ADDR_SPACE_POINTER_TYPE_P (outer_type))
>>     return true;
>>
>> in other places you simply replaced POINTER_TYPE_P with
>> GENERIC_ADDR_SPACE_POINTER_TYPE_P - why is this not
>> correct here?
>
> Because previously, useless_type_conversion_p would eliminate casts
> between a void * and a pointer to any type.  Such casts cannot be
> eliminated when casting (for example) between a pointer in another
> address space and a void * in the generic address space, as some
> computation must be done to translate the address.  Yes, this is a
> special case as far as useless_type_conversion_p is concerned.
>
> Happy to leave this alone?

The point was that POINTER_TYPE_P (inner_type) &&
GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type) looks like
a redundannt test and you should just test
GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type) like you
did in other places?  I understand why you added those, but why
not just exchange the POINTER_TYPE_P tests?

Richard.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-21 10:51     ` Richard Guenther
@ 2008-08-21 11:25       ` Ben Elliston
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-21 11:25 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

On Thu, 2008-08-21 at 11:36 +0200, Richard Guenther wrote:

> The point was that POINTER_TYPE_P (inner_type) &&
> GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type) looks like
> a redundannt test and you should just test
> GENERIC_ADDR_SPACE_POINTER_TYPE_P (inner_type) like you
> did in other places?  I understand why you added those, but why not
> just exchange the POINTER_TYPE_P tests?

Oh, sorry, I missed that point.  Yes, I'll make that change.

Ben


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent  parts)
  2008-08-20 19:49 ` Joseph S. Myers
  2008-08-20 20:49   ` Ben Elliston
@ 2008-08-28 21:30   ` Ben Elliston
  2008-08-28 21:52     ` Joseph S. Myers
  2008-08-30 13:05   ` *revised* " Ben Elliston
  2 siblings, 1 reply; 18+ messages in thread
From: Ben Elliston @ 2008-08-28 21:30 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

Hi Joseph

> > I will post a follow-up patch that brings across the SPU backend
> > changes.
> 
> This will be needed in order to review this first patch properly, as a 
> requirement for review will be an adequate set of testcases, and those 
> will I think necessarily be target-specific.

Did you catch the patch I posted a few days ago?

  http://gcc.gnu.org/ml/gcc-patches/2008-08/msg01929.html

Cheers, Ben


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent   parts)
  2008-08-28 21:30   ` Ben Elliston
@ 2008-08-28 21:52     ` Joseph S. Myers
  2008-08-29  0:40       ` Ben Elliston
  0 siblings, 1 reply; 18+ messages in thread
From: Joseph S. Myers @ 2008-08-28 21:52 UTC (permalink / raw)
  To: Ben Elliston; +Cc: gcc-patches

On Thu, 28 Aug 2008, Ben Elliston wrote:

> Hi Joseph
> 
> > > I will post a follow-up patch that brings across the SPU backend
> > > changes.
> > 
> > This will be needed in order to review this first patch properly, as a 
> > requirement for review will be an adequate set of testcases, and those 
> > will I think necessarily be target-specific.
> 
> Did you catch the patch I posted a few days ago?
> 
>   http://gcc.gnu.org/ml/gcc-patches/2008-08/msg01929.html

Given the various issues I found with the first patch that will require 
changes to the testcases in the second patch, I'm not sure there's much 
point in detailed review of the tests until there are versions of both 
patches updated for the issues I found.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: named address space support (1/2: target-independent   parts)
  2008-08-28 21:52     ` Joseph S. Myers
@ 2008-08-29  0:40       ` Ben Elliston
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-29  0:40 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

> Given the various issues I found with the first patch that will require 
> changes to the testcases in the second patch, I'm not sure there's much 
> point in detailed review of the tests until there are versions of both 
> patches updated for the issues I found.

Fair point.  I will submit the revised patches today.

Thanks,
Ben


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: *revised* PATCH: named address space support (1/2:  target-independent parts)
  2008-08-20 19:49 ` Joseph S. Myers
  2008-08-20 20:49   ` Ben Elliston
  2008-08-28 21:30   ` Ben Elliston
@ 2008-08-30 13:05   ` Ben Elliston
  2008-08-30 13:35     ` Ralf Wildenhues
  2 siblings, 1 reply; 18+ messages in thread
From: Ben Elliston @ 2008-08-30 13:05 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 60639 bytes --]

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));
 }
 \f
@@ -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.  */


[-- Attachment #2: cast1.c --]
[-- Type: text/x-csrc, Size: 388 bytes --]

/* { dg-do run { target spu-*-* } } */
/* { dg-options "-std=gnu99" } */

extern void abort (void);
extern unsigned long long __ea_local_store;

__ea int *ppu;
int x, *spu = &x, *spu2;

int
main (int argc, char **argv)
{
  ppu = (__ea int *) spu;
  spu2 = (int *) ppu;

  if ((int) ppu != (int) __ea_local_store + (int) spu)
    abort ();

  if (spu != spu2)
    abort ();

  return 0;
}

[-- Attachment #3: compile.c --]
[-- Type: text/x-csrc, Size: 1277 bytes --]

/* Valid __ea declarations.  */
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -pedantic-errors" } */

/* Typedefs.  */
typedef __ea int ea_int_t;
typedef __ea int *ea_int_star_t;
typedef int outer_t;

/* Externs.  */

__ea extern int i1;
extern __ea int i2;
extern int __ea i3;
extern __ea ea_int_t i4;		/* __ea qualifier permitted via typedef.  */
extern int __ea __ea __ea dupe;		/* __ea duplicate permitted directly.  */
extern int __ea *ppu;

/* Pointers.  */
__ea int *i4p;

/* Structs.  */
struct st {
  __ea int *p;
};

/* Variable definitions.  */
__ea int ii0;
int *__ea ii1;
static int __ea ii2;

void
f1 ()
{
  int *spu;
  ppu = (ea_int_t *) spu;
  ppu = (ea_int_star_t) spu;
}

void
f2 ()
{
  int *spu;
  spu = (int *) ppu;
  ppu = (__ea int *) spu;
}

void
f3 ()
{
  int i = sizeof (__ea int);
}

__ea int *f4 (void)
{
  return 0;
}

int f5 (__ea int *parm)
{
  static __ea int local4;
  int tmp = local4;
  local4 = *parm;
  return tmp;
}

static inline __ea void *f6 (__ea void *start)
{
  return 0;
}

void f7 (void)
{
  __ea void *s1;
  auto __ea void *s2;
}

__ea int *f8 (__ea int *x)
{
  register __ea int *y = x;
  __ea int *z = y;
  return z;
}

long long f9 (__ea long long x[2])
{
  return x[0] + x[1];
}

void f10 ()
{
  static __ea outer_t o;
}

[-- Attachment #4: cppdefine32.c --]
[-- Type: text/x-csrc, Size: 182 bytes --]

/* Test default __EA32__ define.  */
/* { dg-options "-std=gnu89 -pedantic-errors -mea32" } */
/* { dg-do compile } */

#ifdef __EA32__
int x;
#else
#error __EA32__ undefined
#endif

[-- Attachment #5: cppdefine64.c --]
[-- Type: text/x-csrc, Size: 128 bytes --]

/* { dg-options "-std=gnu89 -mea64" } */
/* { dg-do compile } */

#ifdef __EA64__
int x;
#else
#error __EA64__ undefined
#endif

[-- Attachment #6: errors.c --]
[-- Type: text/x-csrc, Size: 1681 bytes --]

/* Invalid __ea declarations.  */
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -pedantic-errors" } */

extern __ea void f1 ();	 /* { dg-error "'__ea' specified for function 'f1'" } */

void func ()
{
  register __ea int local1; /* { dg-error "'__ea' combined with 'register' qualifier for 'local1'" } */
  auto __ea int local2;     /* { dg-error "'__ea' combined with 'auto' qualifier for 'local2'" } */
  __ea int local3;	    /* { dg-error "'__ea' specified for auto variable 'local3'" } */
  register int *__ea p1;    /* { dg-error "'__ea' combined with 'register' qualifier for 'p1'" } */
  auto char *__ea p2;       /* { dg-error "'__ea' combined with 'auto' qualifier for 'p2'" } */
  void *__ea p3;            /* { dg-error "'__ea' specified for auto variable 'p3'" } */
  register __ea int a1[2];  /* { dg-error "'__ea' combined with 'register' qualifier for 'a1'" } */
  auto __ea char a2[1];     /* { dg-error "'__ea' combined with 'auto' qualifier for 'a2'" } */
  __ea char a3[5];          /* { dg-error "'__ea' specified for auto variable 'a3'" } */
}

void func2 (__ea int x)	    /* { dg-error "'__ea' specified for parameter 'x'" } */
{ }

struct st {
  __ea int x;		    /* { dg-error "'__ea' specified for structure field 'x'" } */
  int *__ea q;		    /* { dg-error "'__ea' specified for structure field 'q'" } */
} s;

__ea int func3 (int x) {    /* { dg-error "'__ea' specified for function 'func3'" } */
  return x;
}

struct A { int a; };

int func4 (int *__ea x)	    /* { dg-error "'__ea' specified for parameter 'x'" } */
{
  struct A i = (__ea struct A) { 1 };	/* { dg-error "compound literal qualified by address-space qualifier" } */
  return i.a;
}

[-- Attachment #7: options1.c --]
[-- Type: text/x-csrc, Size: 98 bytes --]

/* Test -mcache-size.  */
/* { dg-options "-mcache-size=128" } */
/* { dg-do compile } */

int x;

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: *revised* PATCH: named address space support (1/2:  target-independent parts)
  2008-08-30 13:05   ` *revised* " Ben Elliston
@ 2008-08-30 13:35     ` Ralf Wildenhues
  2008-08-30 13:37       ` Ben Elliston
  0 siblings, 1 reply; 18+ messages in thread
From: Ralf Wildenhues @ 2008-08-30 13:35 UTC (permalink / raw)
  To: Ben Elliston; +Cc: Joseph S. Myers, gcc-patches

Hello Ben,

* Ben Elliston wrote on Fri, Aug 29, 2008 at 05:16:32AM CEST:
> 2008-08-28  Ben Elliston  <bje@au.ibm.com>
> 
> 	* c-decl.c: Include targhooks.h.
[...]

AFAICS all #include changes in this patch still need adjustment of
gcc/Makefile.in (several instances).

Cheers,
Ralf

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: *revised* PATCH: named address space support (1/2:  target-independent parts)
  2008-08-30 13:35     ` Ralf Wildenhues
@ 2008-08-30 13:37       ` Ben Elliston
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Elliston @ 2008-08-30 13:37 UTC (permalink / raw)
  To: Ralf Wildenhues; +Cc: Joseph S. Myers, gcc-patches

> AFAICS all #include changes in this patch still need adjustment of
> gcc/Makefile.in (several instances).

Thanks.  Fixed thus:

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

        * Makefile.in (c-decl.o, c-pretty-print.o, convert.o,
        tree-pretty-print.o, fold-const.o): Update make dependencies.

Index: Makefile.in
===================================================================
--- Makefile.in (revision 139749)
+++ Makefile.in (working copy)
@@ -1798,7 +1798,7 @@ c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM
     opts.h $(C_PRAGMA_H) gt-c-decl.h $(CGRAPH_H) $(HASHTAB_H) libfuncs.h \
     except.h $(LANGHOOKS_DEF_H) $(TREE_DUMP_H) $(C_COMMON_H) $(CPPLIB_H) \
     $(DIAGNOSTIC_H) $(INPUT_H) langhooks.h $(GIMPLE_H) tree-mudflap.h  \
-    pointer-set.h $(BASIC_BLOCK_H) $(GIMPLE_H) tree-iterator.h
+    pointer-set.h $(BASIC_BLOCK_H) $(GIMPLE_H) tree-iterator.h targhooks.h
 c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) $(C_TREE_H) $(TARGET_H) $(FLAGS_H) intl.h output.h $(EXPR_H) \
     $(RTL_H) $(TOPLEV_H) $(TM_P_H) langhooks.h $(GGC_H) $(TREE_FLOW_H) \
@@ -1868,7 +1868,8 @@ c-common.o : c-common.c $(CONFIG_H) $(SY
 
 c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
        $(C_TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(REAL_H) \
-       $(DIAGNOSTIC_H) tree-iterator.h fixed-value.h
+       $(DIAGNOSTIC_H) tree-iterator.h fixed-value.h $(TARGET_DEF_H) \
+       $(TARGET_H)
 
 c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)                \
         $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) $(TOPLEV_H) langhooks.h             \
@@ -2019,8 +2020,9 @@ prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_
        -DPREFIX=\"$(prefix)\" -DBASEVER=$(BASEVER_s) \
          -c $(srcdir)/prefix.c $(OUTPUT_OPTION)
 
-convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
-   $(FLAGS_H) convert.h $(TOPLEV_H) langhooks.h $(REAL_H) fixed-value.h
+convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   $(TREE_H) $(FLAGS_H) convert.h $(TOPLEV_H) langhooks.h $(REAL_H) \
+   fixed-value.h $(TARGET_H)
 
 double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
 
@@ -2392,11 +2394,11 @@ tree-nomudflap.o : $(CONFIG_H) $(SYSTEM_
 tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
    $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h \
-   value-prof.h fixed-value.h output.h
+   value-prof.h fixed-value.h output.h $(TARGET_H) $(TARGET_DEF_H)
 fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(FLAGS_H) $(REAL_H) $(TOPLEV_H) $(HASHTAB_H) $(EXPR_H) $(RTL_H) \
    $(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h fixed-value.h $(TARGET_H) \
-   $(GIMPLE_H)
+   $(GIMPLE_H) $(TARGET_H)
 diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) version.h $(TM_P_H) $(FLAGS_H) $(INPUT_H) $(TOPLEV_H) intl.h \
    $(DIAGNOSTIC_H) langhooks.h $(LANGHOOKS_DEF_H) diagnostic.def opts.h


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2008-08-29  6:10 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-20  7:29 PATCH: named address space support (1/2: target-independent parts) Ben Elliston
2008-08-20 10:36 ` Richard Guenther
2008-08-20 12:00   ` Ben Elliston
2008-08-20 12:47     ` C++ support? Re: PATCH: named address space support Ulrich Weigand
2008-08-20 14:05       ` Ben Elliston
2008-08-21  6:03   ` PATCH: named address space support (1/2: target-independent parts) Ben Elliston
2008-08-21 10:51     ` Richard Guenther
2008-08-21 11:25       ` Ben Elliston
2008-08-20 12:11 ` Joseph S. Myers
2008-08-21  8:37   ` Ben Elliston
2008-08-20 19:49 ` Joseph S. Myers
2008-08-20 20:49   ` Ben Elliston
2008-08-28 21:30   ` Ben Elliston
2008-08-28 21:52     ` Joseph S. Myers
2008-08-29  0:40       ` Ben Elliston
2008-08-30 13:05   ` *revised* " Ben Elliston
2008-08-30 13:35     ` Ralf Wildenhues
2008-08-30 13:37       ` Ben Elliston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).