summaryrefslogtreecommitdiff
path: root/gcc/config/i386
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386')
-rw-r--r--gcc/config/i386/cygwin.h2
-rw-r--r--gcc/config/i386/i386-protos.h6
-rw-r--r--gcc/config/i386/i386.c125
-rw-r--r--gcc/config/i386/winnt.c79
4 files changed, 126 insertions, 86 deletions
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index d325167673c..138d96fc740 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -191,7 +191,7 @@ union tree_node;
It's also used to handle dllimport override semantics. */
#if 0
#define REDO_SECTION_INFO_P(DECL) \
- ((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \
+ ((DECL_ATTRIBUTES (DECL) != NULL_TREE) \
|| (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL)))
#else
#define REDO_SECTION_INFO_P(DECL) 1
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index b6462e1f65f..a81a29b02d8 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -173,9 +173,9 @@ extern int ix86_return_pops_args PARAMS ((tree, tree, int));
extern int ix86_data_alignment PARAMS ((tree, int));
extern int ix86_local_alignment PARAMS ((tree, int));
extern int ix86_constant_alignment PARAMS ((tree, int));
-extern int ix86_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
-extern int i386_pe_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree));
-extern int i386_pe_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
+extern tree ix86_handle_dll_attribute PARAMS ((tree *, tree, tree, int, bool *));
+extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool *));
+
extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
int));
extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c89a0ab591d..028c1ac8a17 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -657,6 +657,9 @@ static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
static int ix86_save_reg PARAMS ((int, int));
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
static int ix86_comp_type_attributes PARAMS ((tree, tree));
+const struct attribute_spec ix86_attribute_table[];
+static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
+static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
#ifdef DO_GLOBAL_CTORS_BODY
static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
@@ -667,15 +670,11 @@ static void sco_asm_out_constructor PARAMS ((rtx, int));
#endif
/* Initialize the GCC target structure. */
-#undef TARGET_VALID_TYPE_ATTRIBUTE
+#undef TARGET_ATTRIBUTE_TABLE
+#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
-# define TARGET_VALID_TYPE_ATTRIBUTE i386_pe_valid_type_attribute_p
-# undef TARGET_VALID_DECL_ATTRIBUTE
-# define TARGET_VALID_DECL_ATTRIBUTE i386_pe_valid_decl_attribute_p
# undef TARGET_MERGE_DECL_ATTRIBUTES
# define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
-#else
-# define TARGET_VALID_TYPE_ATTRIBUTE ix86_valid_type_attribute_p
#endif
#undef TARGET_COMP_TYPE_ATTRIBUTES
@@ -977,56 +976,94 @@ optimization_options (level, size)
#endif
}
-/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
- attribute for TYPE. The attributes in ATTRIBUTES have previously been
- assigned to TYPE. */
-
-int
-ix86_valid_type_attribute_p (type, attributes, identifier, args)
- tree type;
- tree attributes ATTRIBUTE_UNUSED;
- tree identifier;
- tree args;
+/* Table of valid machine attributes. */
+const struct attribute_spec ix86_attribute_table[] =
{
- if (TREE_CODE (type) != FUNCTION_TYPE
- && TREE_CODE (type) != METHOD_TYPE
- && TREE_CODE (type) != FIELD_DECL
- && TREE_CODE (type) != TYPE_DECL)
- return 0;
-
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
- if (is_attribute_p ("stdcall", identifier)
- && !TARGET_64BIT)
- return (args == NULL_TREE);
-
- /* Cdecl attribute says the callee is a normal C declaration. */
- if (is_attribute_p ("cdecl", identifier)
- && !TARGET_64BIT)
- return (args == NULL_TREE);
-
+ { "stdcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
+ /* Cdecl attribute says the callee is a normal C declaration */
+ { "cdecl", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
/* Regparm attribute specifies how many integer arguments are to be
passed in registers. */
- if (is_attribute_p ("regparm", identifier))
+ { "regparm", 1, 1, false, true, true, ix86_handle_regparm_attribute },
+#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+ { "dllimport", 1, 1, false, false, false, ix86_handle_dll_attribute },
+ { "dllexport", 1, 1, false, false, false, ix86_handle_dll_attribute },
+ { "shared", 1, 1, true, false, false, ix86_handle_shared_attribute },
+#endif
+ { NULL, 0, 0, false, false, false, NULL }
+};
+
+/* Handle a "cdecl" or "stdcall" attribute;
+ arguments as in struct attribute_spec.handler. */
+static tree
+ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
+ tree args ATTRIBUTE_UNUSED;
+ int flags ATTRIBUTE_UNUSED;
+ bool *no_add_attrs;
+{
+ if (TREE_CODE (*node) != FUNCTION_TYPE
+ && TREE_CODE (*node) != METHOD_TYPE
+ && TREE_CODE (*node) != FIELD_DECL
+ && TREE_CODE (*node) != TYPE_DECL)
{
- tree cst;
+ warning ("`%s' attribute only applies to functions",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
- if (! args || TREE_CODE (args) != TREE_LIST
- || TREE_CHAIN (args) != NULL_TREE
- || TREE_VALUE (args) == NULL_TREE)
- return 0;
+ if (TARGET_64BIT)
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
- cst = TREE_VALUE (args);
- if (TREE_CODE (cst) != INTEGER_CST)
- return 0;
+ return NULL_TREE;
+}
- if (compare_tree_int (cst, REGPARM_MAX) > 0)
- return 0;
+/* Handle a "regparm" attribute;
+ arguments as in struct attribute_spec.handler. */
+static tree
+ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
+ tree args;
+ int flags ATTRIBUTE_UNUSED;
+ bool *no_add_attrs;
+{
+ if (TREE_CODE (*node) != FUNCTION_TYPE
+ && TREE_CODE (*node) != METHOD_TYPE
+ && TREE_CODE (*node) != FIELD_DECL
+ && TREE_CODE (*node) != TYPE_DECL)
+ {
+ warning ("`%s' attribute only applies to functions",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+ else
+ {
+ tree cst;
- return 1;
+ cst = TREE_VALUE (args);
+ if (TREE_CODE (cst) != INTEGER_CST)
+ {
+ warning ("`%s' attribute requires an integer constant argument",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+ else if (compare_tree_int (cst, REGPARM_MAX) > 0)
+ {
+ warning ("argument to `%s' attribute larger than %d",
+ IDENTIFIER_POINTER (name), REGPARM_MAX);
+ *no_add_attrs = true;
+ }
}
- return 0;
+ return NULL_TREE;
}
#if defined (OSF_OS) || defined (TARGET_OSF1ELF)
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index d32224f2382..e14359d1c4b 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Windows NT.
Contributed by Douglas Rupp (drupp@cs.washington.edu)
- Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -49,51 +49,54 @@ int i386_pe_dllimport_p PARAMS ((tree));
void i386_pe_mark_dllexport PARAMS ((tree));
void i386_pe_mark_dllimport PARAMS ((tree));
-/* Return nonzero if ATTR is a valid attribute for DECL.
- ATTRIBUTES are any existing attributes and ARGS are the arguments
- supplied with ATTR. */
-
-int
-i386_pe_valid_decl_attribute_p (decl, attributes, attr, args)
- tree decl;
- tree attributes ATTRIBUTE_UNUSED;
- tree attr;
+/* Handle a "dllimport" or "dllexport" attribute;
+ arguments as in struct attribute_spec.handler. */
+tree
+ix86_handle_dll_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
tree args;
+ int flags;
+ bool *no_add_attrs;
{
- if (args == NULL_TREE)
+ /* These attributes may apply to structure and union types being created,
+ but otherwise should pass to the declaration involved. */
+ if (!DECL_P (*node))
{
- if (is_attribute_p ("dllexport", attr))
- return 1;
- if (is_attribute_p ("dllimport", attr))
- return 1;
- if (is_attribute_p ("shared", attr))
- return TREE_CODE (decl) == VAR_DECL;
+ if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
+ | (int) ATTR_FLAG_ARRAY_NEXT))
+ {
+ *no_add_attrs = true;
+ return tree_cons (name, args, NULL_TREE);
+ }
+ if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
}
- return 0;
+ return NULL_TREE;
}
-/* Return nonzero if ATTR is a valid attribute for TYPE.
- ATTRIBUTES are any existing attributes and ARGS are the arguments
- supplied with ATTR. */
-
-int
-i386_pe_valid_type_attribute_p (type, attributes, attr, args)
- tree type;
- tree attributes;
- tree attr;
- tree args;
+/* Handle a "shared" attribute;
+ arguments as in struct attribute_spec.handler. */
+tree
+ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
+ tree args ATTRIBUTE_UNUSED;
+ int flags ATTRIBUTE_UNUSED;
+ bool *no_add_attrs;
{
- if (args == NULL_TREE
- && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE))
+ if (TREE_CODE (*node) != VAR_DECL)
{
- if (is_attribute_p ("dllexport", attr))
- return 1;
- if (is_attribute_p ("dllimport", attr))
- return 1;
+ warning ("`%s' attribute only applies to variables",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
}
- return ix86_valid_type_attribute_p (type, attributes, attr, args);
+ return NULL_TREE;
}
/* Return the type that we should use to determine if DECL is
@@ -132,7 +135,7 @@ i386_pe_dllexport_p (decl)
if (TREE_CODE (decl) != VAR_DECL
&& TREE_CODE (decl) != FUNCTION_DECL)
return 0;
- exp = lookup_attribute ("dllexport", DECL_MACHINE_ATTRIBUTES (decl));
+ exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
if (exp)
return 1;
@@ -163,7 +166,7 @@ i386_pe_dllimport_p (decl)
if (TREE_CODE (decl) != VAR_DECL
&& TREE_CODE (decl) != FUNCTION_DECL)
return 0;
- imp = lookup_attribute ("dllimport", DECL_MACHINE_ATTRIBUTES (decl));
+ imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
if (imp)
return 1;
@@ -499,7 +502,7 @@ i386_pe_section_type_flags (decl, name, reloc)
flags = SECTION_WRITE;
if (decl && TREE_CODE (decl) == VAR_DECL
- && lookup_attribute ("shared", DECL_MACHINE_ATTRIBUTES (decl)))
+ && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
flags |= SECTION_PE_SHARED;
}