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
This commit is contained in:
Jayant Sonar 2007-05-07 23:13:15 +00:00 committed by DJ Delorie
parent 04055200ed
commit 5abd2125f0
5 changed files with 193 additions and 3 deletions

View File

@ -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

View File

@ -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\";
}"

View File

@ -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

View File

@ -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;

View File

@ -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