diff options
author | Jie Zhang <jie.zhang@analog.com> | 2007-08-29 09:15:14 +0000 |
---|---|---|
committer | Jie Zhang <jiez@gcc.gnu.org> | 2007-08-29 09:15:14 +0000 |
commit | 4af797b5020e8071630f8f48641fc071b2d8350c (patch) | |
tree | 438744c9ed8948abcf533896717c5442e8fddf9c | |
parent | e874e49fdf1e637d510c38b8ca031f6843e3c878 (diff) | |
download | gcc-4af797b5020e8071630f8f48641fc071b2d8350c.zip gcc-4af797b5020e8071630f8f48641fc071b2d8350c.tar.gz gcc-4af797b5020e8071630f8f48641fc071b2d8350c.tar.bz2 |
bfin.c (bfin_expand_call): Inline PLT with l1_text attribute when appropriate.
* config/bfin/bfin.c (bfin_expand_call): Inline PLT with l1_text
attribute when appropriate.
(bfin_handle_l1_text_attribute): New.
(bfin_handle_l1_data_attribute): New.
(bfin_attribute_table): Add attributes: l1_text, l1_data,
l1_data_A and l1_data_B.
* doc/extend.texi (node Function Attributes): Document l1_text
function attribute.
(Variable Attributes): Add Blackfin subsection. Document l1_data,
l1_data_A and l1_data_B variable attributes.
From-SVN: r127887
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/bfin/bfin.c | 110 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 25 |
3 files changed, 147 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49c6def..e4e1bd9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2007-08-29 Jie Zhang <jie.zhang@analog.com> + + * config/bfin/bfin.c (bfin_expand_call): Inline PLT with l1_text + attribute when appropriate. + (bfin_handle_l1_text_attribute): New. + (bfin_handle_l1_data_attribute): New. + (bfin_attribute_table): Add attributes: l1_text, l1_data, + l1_data_A and l1_data_B. + * doc/extend.texi (node Function Attributes): Document l1_text + function attribute. + (Variable Attributes): Add Blackfin subsection. Document l1_data, + l1_data_A and l1_data_B variable attributes. + 2007-08-28 Jie Zhang <jie.zhang@analog.com> * config/bfin/bfin.opt (minline-plt): Add. diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index b34e130..c97f3a7e 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -1879,11 +1879,30 @@ bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall) if (TARGET_FDPIC) { + int caller_has_l1_text, callee_has_l1_text; + + caller_has_l1_text = callee_has_l1_text = 0; + + if (lookup_attribute ("l1_text", + DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE) + caller_has_l1_text = 1; + + if (GET_CODE (callee) == SYMBOL_REF + && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee)) + && lookup_attribute + ("l1_text", + DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE) + callee_has_l1_text = 1; + if (GET_CODE (callee) != SYMBOL_REF || bfin_longcall_p (callee, INTVAL (cookie)) || (GET_CODE (callee) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (callee) - && TARGET_INLINE_PLT)) + && TARGET_INLINE_PLT) + || caller_has_l1_text != callee_has_l1_text + || (caller_has_l1_text && callee_has_l1_text + && (GET_CODE (callee) != SYMBOL_REF + || !SYMBOL_REF_LOCAL_P (callee)))) { rtx addr = callee; if (! address_operand (addr, Pmode)) @@ -4646,6 +4665,91 @@ bfin_handle_longcall_attribute (tree *node, tree name, return NULL_TREE; } +/* Handle a "l1_text" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +bfin_handle_l1_text_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree decl = *node; + + if (TREE_CODE (decl) != FUNCTION_DECL) + { + error ("`%s' attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + /* The decl may have already been given a section attribute + from a previous declaration. Ensure they match. */ + else if (DECL_SECTION_NAME (decl) != NULL_TREE + && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + ".l1.text") != 0) + { + error ("section of %q+D conflicts with previous declaration", + decl); + *no_add_attrs = true; + } + else + DECL_SECTION_NAME (decl) = build_string (9, ".l1.text"); + + return NULL_TREE; +} + +/* Handle a "l1_data", "l1_data_A" or "l1_data_B" attribute; + arguments as in struct attribute_spec.handler. */ + +static tree +bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree decl = *node; + + if (TREE_CODE (decl) != VAR_DECL) + { + error ("`%s' attribute only applies to variables", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (current_function_decl != NULL_TREE + && !TREE_STATIC (decl)) + { + error ("`%s' attribute cannot be specified for local variables", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else + { + const char *section_name; + + if (strcmp (IDENTIFIER_POINTER (name), "l1_data") == 0) + section_name = ".l1.data"; + else if (strcmp (IDENTIFIER_POINTER (name), "l1_data_A") == 0) + section_name = ".l1.data.A"; + else if (strcmp (IDENTIFIER_POINTER (name), "l1_data_B") == 0) + section_name = ".l1.data.B"; + else + gcc_unreachable (); + + /* The decl may have already been given a section attribute + from a previous declaration. Ensure they match. */ + if (DECL_SECTION_NAME (decl) != NULL_TREE + && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + section_name) != 0) + { + error ("section of %q+D conflicts with previous declaration", + decl); + *no_add_attrs = true; + } + else + DECL_SECTION_NAME (decl) + = build_string (strlen (section_name) + 1, section_name); + } + + return NULL_TREE; +} + /* Table of valid machine attributes. */ const struct attribute_spec bfin_attribute_table[] = { @@ -4658,6 +4762,10 @@ const struct attribute_spec bfin_attribute_table[] = { "saveall", 0, 0, false, true, true, NULL }, { "longcall", 0, 0, false, true, true, bfin_handle_longcall_attribute }, { "shortcall", 0, 0, false, true, true, bfin_handle_longcall_attribute }, + { "l1_text", 0, 0, true, false, false, bfin_handle_l1_text_attribute }, + { "l1_data", 0, 0, true, false, false, bfin_handle_l1_data_attribute }, + { "l1_data_A", 0, 0, true, false, false, bfin_handle_l1_data_attribute }, + { "l1_data_B", 0, 0, true, false, false, bfin_handle_l1_data_attribute }, { NULL, 0, 0, false, false, false, NULL } }; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index f0a8b4d..5ae033c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2148,6 +2148,13 @@ When used together with @code{interrupt_handler}, @code{exception_handler} or @code{nmi_handler}, code will be generated to load the stack pointer from the USP register in the function prologue. +@item l1_text +@cindex @code{l1_text} function attribute +This attribute specifies a function to be placed into L1 Instruction +SRAM. The function will be put into a specific section named @code{.l1.text}. +With @option{-mfdpic}, function calls with a such function as the callee +or caller will use inlined PLT. + @item long_call/short_call @cindex indirect calls on ARM This attribute specifies how a particular function is called on @@ -3465,6 +3472,24 @@ The @code{dllexport} attribute is described in @xref{Function Attributes}. @end table +@subsection Blackfin Variable Attributes + +Three attributes are currently defined for the Blackfin. + +@table @code +@item l1_data +@item l1_data_A +@item l1_data_B +@cindex @code{l1_data} variable attribute +@cindex @code{l1_data_A} variable attribute +@cindex @code{l1_data_B} variable attribute +Use these attributes on the Blackfin to place the variable into L1 Data SRAM. +Variables with @code{l1_data} attribute will be put into the specific section +named @code{.l1.data}. Those with @code{l1_data_A} attribute will be put into +the specific section named @code{.l1.data.A}. Those with @code{l1_data_B} +attribute will be put into the specific section named @code{.l1.data.B}. +@end table + @subsection M32R/D Variable Attributes One attribute is currently defined for the M32R/D@. |