From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9729 invoked by alias); 29 Jun 2005 08:48:14 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 9023 invoked by uid 22791); 29 Jun 2005 08:47:46 -0000 Received: from mr2-n.kom.tuwien.ac.at (HELO mr.tuwien.ac.at) (128.131.2.110) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Wed, 29 Jun 2005 08:47:46 +0000 Received: from ahab.auto.tuwien.ac.at (ahab.auto.tuwien.ac.at [128.130.60.8]) by mr.tuwien.ac.at (8.12.10/8.12.8) with ESMTP id j5T8lflm010105; Wed, 29 Jun 2005 10:47:41 +0200 (MEST) Received: from ahab.auto.tuwien.ac.at (localhost.localdomain [127.0.0.1]) by ahab.auto.tuwien.ac.at (8.12.11/8.12.11) with ESMTP id j5T8lfJW008358; Wed, 29 Jun 2005 10:47:41 +0200 Received: (from mkoegler@localhost) by ahab.auto.tuwien.ac.at (8.12.11/8.12.11/Submit) id j5T8leX0008353; Wed, 29 Jun 2005 10:47:40 +0200 Date: Wed, 29 Jun 2005 08:48:00 -0000 From: Martin Koegler To: =?iso-8859-1?Q?Bj=F6rn?= Haase Cc: gcc@gcc.gnu.org Subject: named address spaces (update) Message-ID: <20050629084740.GA8315@ahab.auto.tuwien.ac.at> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.4.1i X-SW-Source: 2005-06/txt/msg01240.txt.bz2 I continued to work on the support for named address spaces in GCC. I managed to move much of the managing code for the namespace attribute into the create funtions of tree nodes, so in most cases, only the language frontends need to assign and check the named address spaces. I moved to creation of the namespace list to the gen-modes program (all examples are taken out of my m68hc05 GCC port http://www.auto.tuwien.ac.at/~mkoegler/index.php/gcc ). A named address space is allocated with NAMESPACE(name) in the mode definition file of the port, eg: NAMESPACE(EEPROM); NAMESPACE(LORAM); (I know, that the NAMESPACE is not the correct naming, but named address space is a bit too long. Any suggestions?) This will result in the address spaces EEPROMspace and LORAMspace. By default the address spaces DEFAULTspace and NONEspace are generated. DEFAULTspace is the normal memory, NONEspace an invalid address space to catch errors. Index: genmodes.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/genmodes.c,v retrieving revision 1.17 diff -u -r1.17 genmodes.c --- genmodes.c 1 Jun 2005 02:55:50 -0000 1.17 +++ genmodes.c 19 Jun 2005 13:02:16 -0000 @@ -104,6 +104,87 @@ static struct mode_adjust *adj_alignment; static struct mode_adjust *adj_format; +/* named address space */ +struct namespace_data +{ + struct namespace_data *next; /* next this class - arbitrary order */ + + const char *name; /* printable mode name without suffix */ + const char *file; /* file and line of definition, */ + unsigned int line; /* for error reporting */ +}; + +static struct namespace_data *namespaces = 0; +static int n_namespaces = 0; +static htab_t namespaces_by_name; + +/* Utility routines. */ +static inline struct namespace_data * +find_namespace (const char *name) +{ + struct mode_data key; + + key.name = name; + return (struct namespace_data *) htab_find (namespaces_by_name, &key); +} + +static struct namespace_data * +new_namespace (const char *name, + const char *file, unsigned int line) +{ + struct namespace_data *m; + + m = find_namespace (name); + if (m) + { + error ("%s:%d: duplicate definition of namespace \"%s\"", + trim_filename (file), line, name); + error ("%s:%d: previous definition here", m->file, m->line); + return m; + } + + m = XNEW (struct namespace_data); + memset (m, 0, sizeof (struct namespace_data)); + m->name = name; + if (file) + m->file = trim_filename (file); + m->line = line; + + m->next = namespaces; + namespaces = m; + n_namespaces++; + + *htab_find_slot (namespaces_by_name, m, INSERT) = m; + + return m; +} + +static hashval_t +hash_namespace (const void *p) +{ + const struct namespace_data *m = (const struct namespace_data *)p; + return htab_hash_string (m->name); +} + +static int +eq_namespace (const void *p, const void *q) +{ + const struct namespace_data *a = (const struct namespace_data *)p; + const struct namespace_data *b = (const struct namespace_data *)q; + + return !strcmp (a->name, b->name); +} + +#define NAMESPACE(N) make_namespace(#N, __FILE__, __LINE__) + +static void +make_namespace (const char *name, + const char *file, unsigned int line) +{ + new_namespace (name, file, line); +} + + /* Mode class operations. */ static enum mode_class complex_class (enum mode_class c) @@ -769,6 +850,7 @@ { int c; struct mode_data *m, *first, *last; + struct namespace_data *n; printf ("/* Generated automatically from machmode.def%s%s\n", HAVE_EXTRA_MODES ? " and " : "", @@ -827,6 +909,23 @@ #if 0 /* disabled for backward compatibility, temporary */ printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const"); #endif + + puts ("\ +\n\ +enum namespace_type\n{\n"); + + for (n = namespaces; n; n = n->next) + { + int count_; + printf (" %sspace,%n", n->name, &count_); + printf ("%*s/* %s:%d */\n", 27 - count_, "", + trim_filename (n->file), n->line); + } + + puts ("\ + MAX_NAMESPACE,\n\ + NUM_NAMESPACES = MAX_NAMESPACE\n\ +};\n"); puts ("\ \n\ #endif /* insn-modes.h */"); @@ -866,6 +965,19 @@ } static void +emit_namespace_name (void) +{ + struct namespace_data *m; + + print_decl ("char *const", "namespace_name", "NUM_NAMESPACES"); + + for (m = namespaces; m; m = m->next) + printf (" \"%s\",\n", m->name); + + print_closer (); +} + +static void emit_mode_name (void) { int c; @@ -1190,6 +1302,7 @@ { emit_insn_modes_c_header (); emit_mode_name (); + emit_namespace_name (); emit_mode_class (); emit_mode_precision (); emit_mode_size (); @@ -1233,6 +1346,7 @@ } modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free); + namespaces_by_name = htab_create_alloc (64, hash_namespace, eq_namespace, 0, xcalloc, free); create_modes (); complete_all_modes (); Index: machmode.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/machmode.def,v retrieving revision 1.31 diff -u -r1.31 machmode.def --- machmode.def 28 Apr 2005 05:38:33 -0000 1.31 +++ machmode.def 19 Jun 2005 13:02:17 -0000 @@ -189,6 +189,9 @@ /* The symbol Pmode stands for one of the above machine modes (usually SImode). The tm.h file specifies which one. It is not a distinct mode. */ +NAMESPACE(DEFAULT); +NAMESPACE(NONE); + /* Local variables: mode:c Index: machmode.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/machmode.h,v retrieving revision 1.39 diff -u -r1.39 machmode.h --- machmode.h 1 Jun 2005 00:20:13 -0000 1.39 +++ machmode.h 19 Jun 2005 13:02:17 -0000 @@ -163,4 +163,9 @@ /* Target-dependent machine mode initialization - in insn-modes.c. */ extern void init_adjust_machine_modes (void); +/* Get the name of namespace N as a string. */ + +extern const char * const namespace_name[NUM_NAMESPACES]; +#define GET_NAMESPACE_NAME(N) namespace_name[N] + #endif /* not HAVE_MACHINE_MODES */ The type tree contains a address space attribute, which store the address space, a pointer (or reference) point to. decls contain the address space, in which they are. expression also contains an address space, in which eg. the members of a structure or array (this expression) are. Index: tree.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.h,v retrieving revision 1.734 diff -u -r1.734 tree.h --- tree.h 4 Jun 2005 17:22:21 -0000 1.734 +++ tree.h 19 Jun 2005 13:02:19 -0000 @@ -1178,6 +1178,8 @@ /* In a LOOP_EXPR node. */ #define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0) +#define EXPR_NAMESPACE(NODE) (EXPR_CHECK (NODE)->exp.namespace) + #ifdef USE_MAPPED_LOCATION /* The source location of this expression. Non-tree_exp nodes such as decls and constants can be shared among multiple locations, so @@ -1297,6 +1299,7 @@ struct tree_common common; source_locus locus; int complexity; + enum namespace_type namespace; tree block; tree GTY ((special ("tree_exp"), desc ("TREE_CODE ((tree) &%0)"))) @@ -1542,6 +1545,7 @@ #define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type.main_variant) #define TYPE_CONTEXT(NODE) (TYPE_CHECK (NODE)->type.context) #define TYPE_LANG_SPECIFIC(NODE) (TYPE_CHECK (NODE)->type.lang_specific) +#define TYPE_NAMESPACE(NODE) (TYPE_CHECK (NODE)->type.namespace) /* For a VECTOR_TYPE node, this describes a different type which is emitted in the debugging output. We use this to describe a vector as a @@ -1739,6 +1743,7 @@ HOST_WIDE_INT alias_set; /* Points to a structure whose details depend on the language in use. */ struct lang_type *lang_specific; + enum namespace_type namespace; }; /* Define accessor macros for information about type inheritance @@ -1920,6 +1925,8 @@ NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file scope". */ #define DECL_CONTEXT(NODE) (DECL_CHECK (NODE)->decl.context) +/* namespace */ +#define DECL_NAMESPACE(NODE) (DECL_CHECK (NODE)->decl.namespace) #define DECL_FIELD_CONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.context) /* In a DECL this is the field where attributes are stored. */ #define DECL_ATTRIBUTES(NODE) (DECL_CHECK (NODE)->decl.attributes) @@ -2447,6 +2454,7 @@ tree assembler_name; tree section_name; tree attributes; + enum namespace_type namespace; rtx rtl; /* RTL representation for object. */ /* In FUNCTION_DECL, if it is inline, holds the saved insn chain. @@ -3503,6 +3511,9 @@ extern tree upper_bound_in_type (tree, tree); extern tree lower_bound_in_type (tree, tree); extern int operand_equal_for_phi_arg_p (tree, tree); +extern enum namespace_type tree_get_namespace (tree); +extern void tree_copy_namespace (tree, tree); + /* In stmt.c */ Index: print-tree.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v retrieving revision 1.100 diff -u -r1.100 print-tree.c --- print-tree.c 31 Mar 2005 00:09:10 -0000 1.100 +++ print-tree.c 19 Jun 2005 13:02:17 -0000 @@ -335,6 +335,8 @@ if (DECL_NONLOCAL (node)) fputs (" nonlocal", file); + fprintf (file, " namespace:%s", GET_NAMESPACE_NAME (DECL_NAMESPACE (node))); + if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node)) fputs (" suppress-debug", file); @@ -528,6 +530,8 @@ if (TYPE_LANG_FLAG_6 (node)) fputs (" type_6", file); + fprintf (file, " namespace:%s", GET_NAMESPACE_NAME (TYPE_NAMESPACE (node))); + mode = TYPE_MODE (node); fprintf (file, " %s", GET_MODE_NAME (mode)); @@ -594,6 +598,9 @@ case tcc_binary: case tcc_reference: case tcc_statement: + if (EXPR_P(node)) + fprintf (file, " namespace:%s", GET_NAMESPACE_NAME( EXPR_NAMESPACE (node))); + if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node)) fputs (" unsigned", file); if (TREE_CODE (node) == BIND_EXPR) If a tree element is created, its address space attribute is automatically computed. Only in a few cases, it needs to be changed. tree_copy_namespace is used for propagating the address space. All build functions of decls, pointer and reference types set the address space to DEFAULTspace, so that in the normal case, no changes in the frontend are necessary. I have not yet verfied, that the use of these functions in the middle-end change a namespace incorrectly. Index: tree.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.c,v retrieving revision 1.485 diff -u -r1.485 tree.c --- tree.c 4 Jun 2005 17:22:20 -0000 1.485 +++ tree.c 19 Jun 2005 13:02:19 -0000 @@ -401,6 +401,7 @@ /* We have not yet computed the alias set for this declaration. */ DECL_POINTER_ALIAS_SET (t) = -1; + DECL_NAMESPACE (t) = NONEspace; break; case tcc_type: @@ -415,6 +416,7 @@ /* We have not yet computed the alias set for this type. */ TYPE_ALIAS_SET (t) = -1; + TYPE_NAMESPACE (t) = NONEspace; break; case tcc_constant: @@ -440,6 +442,7 @@ default: break; } + EXPR_NAMESPACE (t) = NONEspace; break; default: @@ -2279,12 +2282,14 @@ case INDIRECT_REF: result = build_nt (INDIRECT_REF, stabilize_reference_1 (TREE_OPERAND (ref, 0))); + tree_copy_namespace (result,ref); break; case COMPONENT_REF: result = build_nt (COMPONENT_REF, stabilize_reference (TREE_OPERAND (ref, 0)), TREE_OPERAND (ref, 1), NULL_TREE); + tree_copy_namespace (result,ref); break; case BIT_FIELD_REF: @@ -2299,6 +2304,7 @@ stabilize_reference (TREE_OPERAND (ref, 0)), stabilize_reference_1 (TREE_OPERAND (ref, 1)), TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3)); + tree_copy_namespace (result,ref); break; case ARRAY_RANGE_REF: @@ -2306,6 +2312,7 @@ stabilize_reference (TREE_OPERAND (ref, 0)), stabilize_reference_1 (TREE_OPERAND (ref, 1)), TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3)); + tree_copy_namespace (result,ref); break; case COMPOUND_EXPR: @@ -2553,6 +2560,7 @@ t = ggc_alloc_zone_pass_stat (length, &tree_zone); memset (t, 0, sizeof (struct tree_common)); + memset (t, 0, length); TREE_SET_CODE (t, code); @@ -2609,6 +2617,12 @@ break; } + if(code==NOP_EXPR) + tree_copy_namespace(t, node); + else if(code==INDIRECT_REF && node) + EXPR_NAMESPACE(t) = TYPE_NAMESPACE (TREE_TYPE (node)); + + return t; } @@ -2663,6 +2677,13 @@ = (TREE_CODE_CLASS (code) == tcc_reference && arg0 && TREE_THIS_VOLATILE (arg0)); + if(code==COMPOUND_EXPR) + tree_copy_namespace (t, arg1); + else if(code==MODIFY_EXPR) + tree_copy_namespace (t, arg0); + else if(code==MISALIGNED_INDIRECT_REF) + EXPR_NAMESPACE(t) = TYPE_NAMESPACE (TREE_TYPE (arg0)); + return t; } @@ -2709,6 +2730,13 @@ = (TREE_CODE_CLASS (code) == tcc_reference && arg0 && TREE_THIS_VOLATILE (arg0)); + if(code==COMPONENT_REF) + tree_copy_namespace (t, arg0); + else if(code==CALL_EXPR) + EXPR_NAMESPACE (t) = DEFAULTspace; + else if(code==COND_EXPR) + EXPR_NAMESPACE (t)= targetm.merge_namespace(tree_get_namespace(arg1), + tree_get_namespace(arg2)); return t; } @@ -2736,6 +2764,11 @@ = (TREE_CODE_CLASS (code) == tcc_reference && arg0 && TREE_THIS_VOLATILE (arg0)); + if(code==ARRAY_REF) + tree_copy_namespace (t, arg0); + else if(code==TARGET_EXPR) + tree_copy_namespace (t, arg0); + return t; } @@ -2835,6 +2868,9 @@ else if (code == FUNCTION_DECL) DECL_MODE (t) = FUNCTION_MODE; + if(code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) + DECL_NAMESPACE (t) = DEFAULTspace; + /* Set default visibility to whatever the user supplied with visibility_specified depending on #pragma GCC visibility. */ DECL_VISIBILITY (t) = default_visibility; @@ -4425,6 +4461,7 @@ TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all; TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type); TYPE_POINTER_TO (to_type) = t; + TYPE_NAMESPACE (t) = DEFAULTspace; /* Lay out the type. This function has many callers that are concerned with expression-construction, and this simplifies them all. */ @@ -4474,6 +4511,7 @@ TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all; TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (to_type); TYPE_REFERENCE_TO (to_type) = t; + TYPE_NAMESPACE (t) = DEFAULTspace; layout_type (t); @@ -6838,4 +6876,33 @@ return result; } +enum namespace_type +tree_get_namespace (tree t) +{ + if(!t) + return NONEspace; + + if (TREE_CODE (t) == IMAGPART_EXPR || TREE_CODE (t) == REALPART_EXPR) + t = TREE_OPERAND (t, 0); + + if (EXCEPTIONAL_CLASS_P(t)) + return NONEspace; + if (CONSTANT_CLASS_P(t)) + return DEFAULTspace; + if (TREE_CODE(t)==STRING_CST) + return DEFAULTspace; + if (TYPE_P(t)) + return NONEspace; + if (DECL_P(t)) + return DECL_NAMESPACE(t); + else + return EXPR_NAMESPACE(t); +} + +void +tree_copy_namespace (tree to, tree from) +{ + EXPR_NAMESPACE(to) = tree_get_namespace(from); +} + #include "gt-tree.h" It introduces tree new hooks: * compare_namespace checks, if the address space in the first parameter can be converted to the address space of the second parameter. It is used to check, if assignments are possible. * merge_namespace returns for any valid combination (where compare_namespace succeeds in one way) the union address space. * extract_mem_ref_flags takes a tree expression and extracts the MEM_REF_FLAGS for this expression (which should contain the information about the address space). For extract_mem_ref_flags, the funtions check_extract_mem_ref_flags is used at the moment, which fails, if the namespace is missing. This is intended only for debugging purposes. It can be changed to hook_int_tree_0, which will cause, that this changes will not affact any address space unaware backends. Index: target.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/target.h,v retrieving revision 1.135 diff -u -r1.135 target.h --- target.h 31 May 2005 15:51:37 -0000 1.135 +++ target.h 19 Jun 2005 13:02:18 -0000 @@ -49,6 +49,7 @@ #include "tm.h" #include "insn-modes.h" +#include "tree.h" struct stdarg_info; @@ -528,6 +529,21 @@ /* Returns true if target supports the insn within a doloop block. */ bool (*insn_valid_within_doloop) (rtx); + /* extracts MEM_REF_FLAGS out of a tree expression */ + int (*extract_mem_ref_flags) (tree t); + + /* compare, if pointer with first namespace can be converted to the value of + the second namespace + returns + 0 error + 1 ok + 2 issue warning + */ + int (*compare_namespace) (enum namespace_type, enum namespace_type); + + /* returns the super memory area of both parameters */ + enum namespace_type (*merge_namespace) (enum namespace_type, enum namespace_type); + /* Functions relating to calls - argument passing, returns, etc. */ struct calls { bool (*promote_function_args) (tree fntype); Index: target-def.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/target-def.h,v retrieving revision 1.123 diff -u -r1.123 target-def.h --- target-def.h 31 May 2005 15:51:37 -0000 1.123 +++ target-def.h 19 Jun 2005 13:02:18 -0000 @@ -393,6 +393,13 @@ #define TARGET_STDARG_OPTIMIZE_HOOK 0 +/* #define TARGET_EXTRACT_MEM_REF_FLAGS hook_int_tree_0 */ +#define TARGET_EXTRACT_MEM_REF_FLAGS check_extract_mem_ref_flags + +#define TARGET_COMPARE_NAMESPACE default_compare_namespace + +#define TARGET_MERGE_NAMESPACE default_merge_namespace + #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_false #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_false #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false @@ -560,6 +567,9 @@ TARGET_DWARF_HANDLE_FRAME_UNSPEC, \ TARGET_STDARG_OPTIMIZE_HOOK, \ TARGET_INSN_VALID_WITHIN_DOLOOP, \ + TARGET_EXTRACT_MEM_REF_FLAGS, \ + TARGET_COMPARE_NAMESPACE, \ + TARGET_MERGE_NAMESPACE, \ TARGET_CALLS, \ TARGET_CXX, \ TARGET_HAVE_NAMED_SECTIONS, \ Index: targhooks.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/targhooks.c,v retrieving revision 2.40 diff -u -r2.40 targhooks.c --- targhooks.c 26 May 2005 18:14:47 -0000 2.40 +++ targhooks.c 19 Jun 2005 13:02:18 -0000 @@ -327,3 +327,34 @@ { return NULL; } + +int +default_compare_namespace (enum namespace_type to ATTRIBUTE_UNUSED, + enum namespace_type from ATTRIBUTE_UNUSED) +{ + return 1; +} + +enum namespace_type +default_merge_namespace (enum namespace_type a ATTRIBUTE_UNUSED, + enum namespace_type b ATTRIBUTE_UNUSED) +{ + return DEFAULTspace; +} + +/* check namespace */ +int +check_extract_mem_ref_flags (tree expr) +{ + enum namespace_type ref = tree_get_namespace(expr); + if (TYPE_P (expr)) + ref = DEFAULTspace; + + if(ref == NONEspace) + { + if(TREE_CODE (expr) == CONSTRUCTOR) + ref=DEFAULTspace; + } + gcc_assert (ref!=NONEspace); + return 0; +} Index: targhooks.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/targhooks.h,v retrieving revision 2.28 diff -u -r2.28 targhooks.h --- targhooks.h 25 May 2005 11:52:12 -0000 2.28 +++ targhooks.h 19 Jun 2005 13:02:18 -0000 @@ -62,3 +62,6 @@ (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); extern const char *hook_invalid_arg_for_unprototyped_fn (tree, tree, tree); +extern int check_extract_mem_ref_flags (tree expr); +extern int default_compare_namespace (enum namespace_type, enum namespace_type); +extern enum namespace_type default_merge_namespace (enum namespace_type, enum namespace_type); Defition and handling of the MEM_REF_FLAGS: Index: emit-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v retrieving revision 1.440 diff -u -r1.440 emit-rtl.c --- emit-rtl.c 28 Apr 2005 05:03:02 -0000 1.440 +++ emit-rtl.c 19 Jun 2005 13:02:15 -0000 @@ -55,6 +55,7 @@ #include "ggc.h" #include "debug.h" #include "langhooks.h" +#include "target.h" /* Commonly used modes. */ @@ -1450,6 +1454,8 @@ if (t == NULL_TREE) return; + MEM_REF_FLAGS(ref) = targetm.extract_mem_ref_flags (t); + type = TYPE_P (t) ? t : TREE_TYPE (t); if (type == error_mark_node) return; @@ -1686,6 +1692,10 @@ = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg), GEN_INT (REG_OFFSET (reg)), MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem)); + + if(REG_EXPR (reg)) + MEM_REF_FLAGS(mem) = targetm.extract_mem_ref_flags (REG_EXPR (reg)); + } /* Set the alias set of MEM to SET. */ Index: gengtype.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v retrieving revision 1.75 diff -u -r1.75 gengtype.c --- gengtype.c 17 May 2005 20:11:42 -0000 1.75 +++ gengtype.c 19 Jun 2005 13:02:16 -0000 @@ -531,6 +531,8 @@ case '0': if (i == MEM && aindex == 1) t = mem_attrs_tp, subname = "rt_mem"; + else if (i == MEM && aindex == 2) + t = scalar_tp, subname = "rt_int"; else if (i == JUMP_INSN && aindex == 9) t = rtx_tp, subname = "rt_rtx"; else if (i == CODE_LABEL && aindex == 4) Index: print-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v retrieving revision 1.123 diff -u -r1.123 print-rtl.c --- print-rtl.c 28 Apr 2005 05:38:34 -0000 1.123 +++ print-rtl.c 19 Jun 2005 13:02:17 -0000 @@ -578,6 +578,8 @@ if (MEM_ALIGN (in_rtx) != 1) fprintf (outfile, " A%u", MEM_ALIGN (in_rtx)); + fprintf (outfile, " %08X", MEM_REF_FLAGS (in_rtx)); + fputc (']', outfile); break; Index: rtl.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.def,v retrieving revision 1.100 diff -u -r1.100 rtl.def --- rtl.def 22 Jan 2005 22:48:57 -0000 1.100 +++ rtl.def 19 Jun 2005 13:02:17 -0000 @@ -385,8 +385,9 @@ /* A memory location; operand is the address. The second operand is the alias set to which this MEM belongs. We use `0' instead of `w' for this - field so that the field need not be specified in machine descriptions. */ -DEF_RTL_EXPR(MEM, "mem", "e0", RTX_OBJ) + field so that the field need not be specified in machine descriptions. + the third the memory flags */ +DEF_RTL_EXPR(MEM, "mem", "e00", RTX_OBJ) /* Reference to an assembler label in the code for this function. The operand is a CODE_LABEL found in the insn chain. Index: rtl.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.h,v retrieving revision 1.551 diff -u -r1.551 rtl.h --- rtl.h 1 Jun 2005 11:38:49 -0000 1.551 +++ rtl.h 19 Jun 2005 13:02:17 -0000 @@ -1056,6 +1056,9 @@ in the block and provide defaults if none specified. */ #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1) +/* A set of flags on a mem */ +#define MEM_REF_FLAGS(RTX) X0INT ((RTX), 2) + /* The register attribute block. We provide access macros for each value in the block and provide defaults if none specified. */ #define REG_ATTRS(RTX) X0REGATTR (RTX, 2) @@ -1106,6 +1109,7 @@ MEM_NOTRAP_P (LHS) = MEM_NOTRAP_P (RHS), \ MEM_READONLY_P (LHS) = MEM_READONLY_P (RHS), \ MEM_KEEP_ALIAS_SET_P (LHS) = MEM_KEEP_ALIAS_SET_P (RHS), \ + MEM_REF_FLAGS (LHS) = MEM_REF_FLAGS (RHS), \ MEM_ATTRS (LHS) = MEM_ATTRS (RHS)) /* 1 if RTX is a label_ref to a label outside the loop containing the The C frontend is extended to support the handling of the address space attributes. Setting them is done using attributes in backend. Index: c-decl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v retrieving revision 1.662 diff -u -r1.662 c-decl.c --- c-decl.c 6 Jun 2005 19:31:24 -0000 1.662 +++ c-decl.c 19 Jun 2005 13:02:14 -0000 @@ -3638,7 +3638,9 @@ return error_mark_node; stmt = build_stmt (DECL_EXPR, decl); + tree_copy_namespace(stmt,decl); complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt); + tree_copy_namespace(complit,decl); TREE_SIDE_EFFECTS (complit) = 1; layout_decl (decl, 0); Index: c-typeck.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v retrieving revision 1.449 diff -u -r1.449 c-typeck.c --- c-typeck.c 6 Jun 2005 19:31:25 -0000 1.449 +++ c-typeck.c 19 Jun 2005 13:02:15 -0000 @@ -652,7 +652,7 @@ { tree t1 = type1; tree t2 = type2; - int attrval, val; + int attrval, val, memareaval; /* Suppress errors caused by previously reported errors. */ @@ -717,6 +717,12 @@ break; val = (TREE_TYPE (t1) == TREE_TYPE (t2) ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); + memareaval = targetm.compare_namespace (TYPE_NAMESPACE(t1), + TYPE_NAMESPACE(t2)); + if(!memareaval) + return 0; + if(memareaval == 2 && val == 1) + val = 2; break; case FUNCTION_TYPE: @@ -3033,6 +3039,15 @@ } else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) { + int memarea_cmp1 = targetm.compare_namespace (TYPE_NAMESPACE(type1), + TYPE_NAMESPACE(type2)); + int memarea_cmp2 = targetm.compare_namespace (TYPE_NAMESPACE(type2), + TYPE_NAMESPACE(type1)); + if(!memarea_cmp1 && !memarea_cmp2) + error (N_("incompatible memory areas used")); + if(memarea_cmp1==2 && memarea_cmp2==2) + warning (0, N_("incompatible memory areas used")); + if (comp_target_types (type1, type2)) result_type = common_pointer_type (type1, type2); else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node @@ -3062,6 +3077,8 @@ pedwarn ("pointer type mismatch in conditional expression"); result_type = build_pointer_type (void_type_node); } + TYPE_NAMESPACE(result_type)=targetm.merge_namespace(TYPE_NAMESPACE(type1), + TYPE_NAMESPACE(type2)); } else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) { @@ -3769,6 +3786,13 @@ bool is_opaque_pointer; int target_cmp = 0; /* Cache comp_target_types () result. */ + int memarea_cmp = targetm.compare_namespace (TYPE_NAMESPACE(type), + TYPE_NAMESPACE(rhstype)); + if(!memarea_cmp) + error(N_("incompatible memory areas used")); + if(memarea_cmp==2) + warning (0, N_("incompatible memory areas used")); + if (TREE_CODE (mvl) != ARRAY_TYPE) mvl = TYPE_MAIN_VARIANT (mvl); if (TREE_CODE (mvr) != ARRAY_TYPE) @@ -7675,6 +7699,16 @@ { tree tt0 = TREE_TYPE (type0); tree tt1 = TREE_TYPE (type1); + + int memarea_cmp1 = targetm.compare_namespace (TYPE_NAMESPACE(type0), + TYPE_NAMESPACE(type1)); + int memarea_cmp2 = targetm.compare_namespace (TYPE_NAMESPACE(type1), + TYPE_NAMESPACE(type0)); + if(!memarea_cmp1 && !memarea_cmp2) + error(N_("incompatible memory areas used")); + if(memarea_cmp1==2 && memarea_cmp2==2) + warning (0, N_("incompatible memory areas used")); + /* Anything compares with void *. void * compares with anything. Otherwise, the targets must be compatible and both must be object or both incomplete. */ @@ -7732,6 +7766,15 @@ short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { + int memarea_cmp1 = targetm.compare_namespace (TYPE_NAMESPACE(type0), + TYPE_NAMESPACE(type1)); + int memarea_cmp2 = targetm.compare_namespace (TYPE_NAMESPACE(type1), + TYPE_NAMESPACE(type0)); + if(!memarea_cmp1&&!memarea_cmp2) + error(N_("incompatible memory areas used")); + if(memarea_cmp1==2&&memarea_cmp2==2) + warning(0, N_("incompatible memory areas used")); + if (comp_target_types (type0, type1)) { result_type = common_pointer_type (type0, type1); Index: cp/decl2.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v retrieving revision 1.785 diff -u -r1.785 decl2.c --- cp/decl2.c 6 Jun 2005 14:18:06 -0000 1.785 +++ cp/decl2.c 19 Jun 2005 13:02:19 -0000 @@ -2001,6 +2001,7 @@ { if (!targetm.cxx.guard_mask_bit ()) { + tree orig = guard; /* We only set the first byte of the guard, in order to leave room for a mutex in the high-order bits. */ guard = build1 (ADDR_EXPR, @@ -2010,6 +2011,7 @@ build_pointer_type (char_type_node), guard); guard = build1 (INDIRECT_REF, char_type_node, guard); + tree_copy_namespace (guard, orig); } return guard; As attribute handler, my backend uses: /* Handle a "eeprom" attribute; arguments as in struct attribute_spec.handler. */ static tree m68hc05_handle_eeprom_attribute (tree * node, tree name, tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, bool * no_add_attrs ATTRIBUTE_UNUSED) { if (POINTER_TYPE_P (*node)) { *node = copy_node (*node); TYPE_NAMESPACE (*node) = EEPROMspace; } else if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL) { *node = copy_node (*node); DECL_NAMESPACE (*node) = EEPROMspace; } else warning (0, "%qs attribute does not apply", IDENTIFIER_POINTER (name)); return NULL_TREE; } The attributes are defined as: {"eepromt", 0, 0, false, true, false, m68hc05_handle_eeprom_attribute}, {"eeprom", 0, 0, true, false, false, m68hc05_handle_eeprom_attribute}, It uses two attributes, as an attribute can not be a decl and type attribute at the same time. The extract_mem_ref_flags hook is similare to check_extract_mem_ref_flags, it additionally converts the ref variable into an return value. The expander check for the EEPROM address space and generate differnt code, if present. The LORAM space is check by extra_constaints and causes an other alternative to be selected. Limitations are: * If one namespace is part of an other namespace, the conversation between them must be a simple move (ie they must have the same addresses). * All pointer have Pmode size. mfg Martin Kögler