* 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
* 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 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-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 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
* 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-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 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).