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