diff options
author | Jayant Sonar <jayants@kpitcummins.com> | 2007-05-07 23:13:15 +0000 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2007-05-07 19:13:15 -0400 |
commit | 5abd2125f012351411df08f07918667ce3e418a9 (patch) | |
tree | b4d7248e78a4d9cbf0ccb466af301868b241de83 | |
parent | 04055200edcb139e4be7088107191b7a1a9089fa (diff) | |
download | gcc-5abd2125f012351411df08f07918667ce3e418a9.zip gcc-5abd2125f012351411df08f07918667ce3e418a9.tar.gz gcc-5abd2125f012351411df08f07918667ce3e418a9.tar.bz2 |
m32c.c (SYMBOL_FLAG_FUNCVEC_FUNCTION): Define.
* config/m32c/m32c.c (SYMBOL_FLAG_FUNCVEC_FUNCTION): Define.
(TARGET_ENCODE_SECTION_INFO): Re-define.
(m32c_encode_section_info): New
(function_vector_handler): New
(current_function_special_page_vector): New
(m32c_special_page_vector_p): New.
* config/m32c/m32c-protos.h (m32c_special_page_vector_p):
Prototype.
* config/m32c/jump.md: Added instruction JSRS for functions
with attribute "function_vector".
* doc/extend.texi (function_vector): Added description
for M16C, M32C targets.
From-SVN: r124523
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/m32c/jump.md | 26 | ||||
-rw-r--r-- | gcc/config/m32c/m32c-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/m32c/m32c.c | 118 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 36 |
5 files changed, 193 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d6c0db..9452c04 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2007-05-07 Jayant Sonar <jayants@kpitcummins.com> + + * config/m32c/m32c.c (SYMBOL_FLAG_FUNCVEC_FUNCTION): Define. + (TARGET_ENCODE_SECTION_INFO): Re-define. + (m32c_encode_section_info): New + (function_vector_handler): New + (current_function_special_page_vector): New + (m32c_special_page_vector_p): New. + * config/m32c/m32c-protos.h (m32c_special_page_vector_p): + Prototype. + * config/m32c/jump.md: Added instruction JSRS for functions + with attribute "function_vector". + * doc/extend.texi (function_vector): Added description + for M16C, M32C targets. + 2007-05-07 DJ Delorie <dj@redhat.com> PR 31794 diff --git a/gcc/config/m32c/jump.md b/gcc/config/m32c/jump.md index 4a358ea..f0983d1 100644 --- a/gcc/config/m32c/jump.md +++ b/gcc/config/m32c/jump.md @@ -69,7 +69,18 @@ "" "* switch (which_alternative) { - case 0: return \"jsr.a\t%0\"; + case 0: + { + HOST_WIDE_INT func_vect_num = + current_function_special_page_vector(XEXP (operands[0], 0)); + if (func_vect_num) + { + operands[3] = gen_rtx_CONST_INT (VOIDmode, func_vect_num); + return \"jsrs\t%3\"; + } + else + return \"jsr.a\t%0\"; + } case 1: return TARGET_A16 ? \"push.w %a0 | jsr.a\tm32c_jsri16\" : \"jsri.a\t%a0\"; case 2: return \"jsri.a\t%a0\"; }" @@ -84,7 +95,18 @@ switch (which_alternative) { "" "* switch (which_alternative) { - case 0: return \"jsr.a\t%1\"; + case 0: + { + HOST_WIDE_INT func_vect_num = + current_function_special_page_vector(XEXP (operands[1], 0)); + if (func_vect_num) + { + operands[4] = gen_rtx_CONST_INT (VOIDmode, func_vect_num); + return \"jsrs\t%4\"; + } + else + return \"jsr.a\t%1\"; + } case 1: return TARGET_A16 ? \"push.w %a1 | jsr.a\tm32c_jsri16\" : \"jsri.a\t%a1\"; case 2: return \"jsri.a\t%a1\"; }" diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h index 5735ee7..5bbc67c 100644 --- a/gcc/config/m32c/m32c-protos.h +++ b/gcc/config/m32c/m32c-protos.h @@ -112,6 +112,7 @@ void m32c_function_arg_advance (CUMULATIVE_ARGS *, MM, tree, int); tree m32c_gimplify_va_arg_expr (tree, tree, tree *, tree *); void m32c_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); bool m32c_promote_function_return (tree); +int m32c_special_page_vector_p (tree); #endif diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index de7ce9d..dd0bce3 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -61,6 +61,7 @@ typedef enum } Push_Pop_Type; static tree interrupt_handler (tree *, tree, tree, int, bool *); +static tree function_vector_handler (tree *, tree, tree, int, bool *); static int interrupt_p (tree node); static bool m32c_asm_integer (rtx, unsigned int, int); static int m32c_comp_type_attributes (tree, tree); @@ -75,6 +76,9 @@ static bool m32c_strict_argument_naming (CUMULATIVE_ARGS *); static rtx m32c_struct_value_rtx (tree, int); static rtx m32c_subreg (enum machine_mode, rtx, enum machine_mode, int); static int need_to_save (int); +int current_function_special_page_vector (rtx); + +#define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0) #define streq(a,b) (strcmp ((a), (b)) == 0) @@ -2721,10 +2725,104 @@ interrupt_handler (tree * node ATTRIBUTE_UNUSED, return NULL_TREE; } +/* Returns TRUE if given tree has the "function_vector" attribute. */ +int +m32c_special_page_vector_p (tree func) +{ + if (TREE_CODE (func) != FUNCTION_DECL) + return 0; + + tree list = M32C_ATTRIBUTES (func); + while (list) + { + if (is_attribute_p ("function_vector", TREE_PURPOSE (list))) + return 1; + list = TREE_CHAIN (list); + } + return 0; +} + +static tree +function_vector_handler (tree * node ATTRIBUTE_UNUSED, + tree name ATTRIBUTE_UNUSED, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs ATTRIBUTE_UNUSED) +{ + if (TARGET_R8C) + { + /* The attribute is not supported for R8C target. */ + warning (OPT_Wattributes, + "`%s' attribute is not supported for R8C target", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (TREE_CODE (*node) != FUNCTION_DECL) + { + /* The attribute must be applied to functions only. */ + warning (OPT_Wattributes, + "`%s' attribute applies only to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (TREE_CODE (TREE_VALUE (args)) != INTEGER_CST) + { + /* The argument must be a constant integer. */ + warning (OPT_Wattributes, + "`%s' attribute argument not an integer constant", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (TREE_INT_CST_LOW (TREE_VALUE (args)) < 18 + || TREE_INT_CST_LOW (TREE_VALUE (args)) > 255) + { + /* The argument value must be between 18 to 255. */ + warning (OPT_Wattributes, + "`%s' attribute argument should be between 18 to 255", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + return NULL_TREE; +} + +/* If the function is assigned the attribute 'function_vector', it + returns the function vector number, otherwise returns zero. */ +int +current_function_special_page_vector (rtx x) +{ + int num; + + if ((GET_CODE(x) == SYMBOL_REF) + && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) + { + tree t = SYMBOL_REF_DECL (x); + + if (TREE_CODE (t) != FUNCTION_DECL) + return 0; + + tree list = M32C_ATTRIBUTES (t); + while (list) + { + if (is_attribute_p ("function_vector", TREE_PURPOSE (list))) + { + num = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (list))); + return num; + } + + list = TREE_CHAIN (list); + } + + return 0; + } + else + return 0; +} + #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE m32c_attribute_table static const struct attribute_spec m32c_attribute_table[] = { {"interrupt", 0, 0, false, false, false, interrupt_handler}, + {"function_vector", 1, 1, true, false, false, function_vector_handler}, {0, 0, 0, 0, 0, 0, 0} }; @@ -3751,6 +3849,23 @@ m32c_scc_pattern(rtx *operands, RTX_CODE code) return buf; } +/* Encode symbol attributes of a SYMBOL_REF into its + SYMBOL_REF_FLAGS. */ +static void +m32c_encode_section_info (tree decl, rtx rtl, int first) +{ + int extra_flags = 0; + + default_encode_section_info (decl, rtl, first); + if (TREE_CODE (decl) == FUNCTION_DECL + && m32c_special_page_vector_p (decl)) + + extra_flags = SYMBOL_FLAG_FUNCVEC_FUNCTION; + + if (extra_flags) + SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags; +} + /* Returns TRUE if the current function is a leaf, and thus we can determine which registers an interrupt function really needs to save. The logic below is mostly about finding the insn sequence @@ -4164,6 +4279,9 @@ m32c_output_compare (rtx insn, rtx *operands) return template + 1; } +#undef TARGET_ENCODE_SECTION_INFO +#define TARGET_ENCODE_SECTION_INFO m32c_encode_section_info + /* The Global `targetm' Variable. */ struct gcc_target targetm = TARGET_INITIALIZER; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 45a6324..1069892 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1972,7 +1972,7 @@ is used. @xref{C Dialect Options,,Options Controlling C Dialect}. @item function_vector -@cindex calling functions through the function vector on the H8/300 processors +@cindex calling functions through the function vector on H8/300, M16C, and M32C processors Use this attribute on the H8/300, H8/300H, and H8S to indicate that the specified function should be called through the function vector. Calling a function through the function vector will reduce code size, however; @@ -1982,6 +1982,40 @@ and 64 entries on the H8/300H and H8S) and shares space with the interrupt vecto You must use GAS and GLD from GNU binutils version 2.7 or later for this attribute to work correctly. +On M16C/M32C targets, the @code{function_vector} attribute declares a +special page subroutine call function. Use of this attribute reduces +the code size by 2 bytes for each call generated to the +subroutine. The argument to the attribute is the vector number entry +from the special page vector table which contains the 16 low-order +bits of the subroutine's entry address. Each vector table has special +page number (18 to 255) which are used in @code{jsrs} instruction. +Jump addresses of the routines are generated by adding 0x0F0000 (in +case of M16C targets) or 0xFF0000 (in case of M32C targets), to the 2 +byte addresses set in the vector table. Therefore you need to ensure +that all the special page vector routines should get mapped within the +address range 0x0F0000 to 0x0FFFFF (for M16C) and 0xFF0000 to 0xFFFFFF +(for M32C). + +In the following example 2 bytes will be saved for each call to +function @code{foo}. + +@smallexample +void foo (void) __attribute__((function_vector(0x18))); +void foo (void) +@{ +@} + +void bar (void) +@{ + foo(); +@} +@end smallexample + +If functions are defined in one file and are called in another file, +then be sure to write this declaration in both files. + +This attribute is ignored for R8C target. + @item interrupt @cindex interrupt handler functions Use this attribute on the ARM, AVR, C4x, CRX, M32C, M32R/D, MS1, and Xstormy16 |