--- gcc-3.4.3/gcc/config/h8300/h8300.c 2004-02-09 22:55:35.000000000 +0530 +++ gcc-3.4.3/gcc/config/h8300/h8300.c.new 2005-01-13 13:34:16.000000000 +0530 @@ -61,6 +61,7 @@ static const char *cond_string (enum rtx static unsigned int h8300_asm_insn_count (const char *); static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *); static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *); +static tree h8300_handle_function_vector_attribute (tree *, tree, tree, int, bool *); static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *); #ifndef OBJECT_FORMAT_ELF static void h8300_asm_named_section (const char *, unsigned int); @@ -1127,6 +1128,7 @@ h8300_rtx_costs (rtx x, int code, int ou /* Documentation for the machine specific operand escapes: + 'C' print jsr operand 'E' like s but negative. 'F' like t but negative. 'G' constant just the negative @@ -1198,6 +1200,44 @@ print_operand (FILE *file, rtx x, int co switch (code) { + case 'C': + switch (GET_CODE (x)) + { + case MEM: + { + rtx inside = XEXP (x, 0); + if (GET_CODE (inside) == SYMBOL_REF + && (SYMBOL_REF_FLAGS (inside) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) + { + int func_vect_num; + tree t; + t = SYMBOL_REF_DECL (inside); + + if (TREE_VALUE (DECL_ATTRIBUTES (t)) == NULL_TREE) + { + fprintf (file,"@"); + print_operand_address (file, inside); + } + else + { + + func_vect_num = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (lookup_attribute ("function_vector", + DECL_ATTRIBUTES (t))))); + fprintf (file,"@%d:8",func_vect_num); + } + } + else + { + print_operand_address (file, inside); + } + + + } + break; + default: + abort (); + } + break; case 'E': switch (GET_CODE (x)) { @@ -4240,12 +4280,50 @@ const struct attribute_spec h8300_attrib { "saveall", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, - { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute }, + { "function_vector", 0, 1, true, false, false, h8300_handle_fndecl_attribute }, { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute }, { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute }, { NULL, 0, 0, false, false, false, NULL } }; +/* Handle a "function_vector" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +h8300_handle_function_vector_attribute (tree *node, tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning ("`%s' attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (list_length (args) == 0) + /*Also support this attribute without argument.*/ + { + return NULL_TREE; + } + else if (TREE_CODE (TREE_VALUE (args)) != INTEGER_CST) + { + /* The argument must be a constant integer. */ + warning ("`%s' attribute argument not an integer constant", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (TREE_INT_CST_LOW (TREE_VALUE (args)) > 255 + || TREE_INT_CST_HIGH (TREE_VALUE (args)) != 0) + { + /* The argument must be within 0-255 */ + warning ("`%s' attribute argument must be in range between 0 and 255", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} /* Handle an attribute requiring a FUNCTION_DECL; arguments as in struct attribute_spec.handler. */ --- gcc-3.4.3/gcc/config/h8300/h8300.md 2004-01-25 08:09:22.000000000 +0530 +++ gcc-3.4.3/gcc/config/h8300/h8300.md.new 2005-01-10 14:06:47.000000000 +0530 @@ -1816,14 +1816,7 @@ [(call (match_operand:QI 0 "call_insn_operand" "or") (match_operand:HI 1 "general_operand" "g"))] "" - "* -{ - if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF - && SYMBOL_REF_FLAG (XEXP (operands[0], 0))) - return \"jsr\\t@%0:8\"; - else - return \"jsr\\t%0\"; -}" + "jsr @%C0" [(set_attr "cc" "clobber") (set (attr "length") (if_then_else (match_operand:QI 0 "small_call_insn_operand" "") @@ -1840,14 +1833,7 @@ (call (match_operand:QI 1 "call_insn_operand" "or") (match_operand:HI 2 "general_operand" "g")))] "" - "* -{ - if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF - && SYMBOL_REF_FLAG (XEXP (operands[1], 0))) - return \"jsr\\t@%1:8\"; - else - return \"jsr\\t%1\"; -}" + "jsr @%C1" [(set_attr "cc" "clobber") (set (attr "length") (if_then_else (match_operand:QI 0 "small_call_insn_operand" "") --- gcc-3.4.3/gcc/doc/extend.texi.orig 2005-01-10 15:29:24.000000000 +0530 +++ gcc-3.4.3/gcc/doc/extend.texi 2005-01-10 15:34:45.000000000 +0530 @@ -2486,7 +2486,7 @@ contents of that register. The @code{s the offset to the function from the call site into the @samp{BL} instruction directly. -@item function_vector +@item function_vector (@var{vector_address}) @cindex calling functions through the function vector on the H8/300 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 @@ -2494,6 +2494,29 @@ function through the function vector wil the function vector has a limited size (maximum 128 entries on the H8/300 and 64 entries on the H8/300H and H8S) and shares space with the interrupt vector. +The "@var{vector_address}" is integer constant in the range from 0 to 255. This +argument is optional. It is used to explicitly specify the vector address for memory +indirect functional call. + +Compiler uses 2 bytes instead of 4 bytes to call a function declared with this +attribute. For this compiler uses memory indirect call using jsr @@aa:8 instruction. + +For example, following call to "foo" will use 2 bytes instead of 4 bytes. Compiler +will use jsr @@16:8 instruction to call "foo". Also ensure that address of "foo" +must be present at location 0x10. + +@smallexample +void foo (void) __attribute__ ((function_vector(0x10))); +void foo (void) +@{ +@} + +void bar (void) +@{ + foo(); +@} +@end smallexample + You must use GAS and GLD from GNU binutils version 2.7 or later for this attribute to work correctly. --- /dev/null 2002-08-31 05:01:37.000000000 +0530 +++ gcc-3.4.3/gcc/testsuite/gcc.dg/func-vect.c 2005-01-07 10:38:53.000000000 +0530 @@ -0,0 +1,15 @@ +/* Test for function_vector attribute. */ +/* Origin: Asgari Jinia */ +/* { dg-do compile {target h8300*-*-*}} */ +/* { dg-final { scan-assembler "jsr\t@@16:8" } } */ + +void foo(void) __attribute__((function_vector(16))); +void foo(void) +{ + +} + +void bar(void) +{ + foo(); +}