Commit 561642fa by Anil Paranjape Committed by Kaz Kojima

sh.c (SH_ATTRIBUTES): Define.

	* config/sh/sh.c (SH_ATTRIBUTES): Define.
	(SYMBOL_FLAG_FUNCVEC_FUNCTION): Define.
	(print_operand): Handle resbank in %@ operand code.
	(sh_encode_section_info): New.
	(push_regs): Add conditions for resbank.
	(sh_expand_epilogue): Likewise.
	(sh_insert_attributes): Likewise.
	(sh_attribute_table): Likewise.
	(sh_handle_resbank_handler_attribute): New.
	(sh2a_handle_function_vector_handler_attribute): New.
	(sh2a_is_function_vector_call): New.
	(sh2a_get_function_vector_number): New.
	(sh2a_function_vector_p): New.
	(sh_cfun_resbank_handler_p): New.
	* config/sh/sh.md (calli): Emit jsr/n if possible.
	(calli_tbr_rel): New.
	(calli_pcrel): Emit jsr/n if possible.
	(return_i): Emit rts/n if possible.
	(call_valuei_tbr_rel): New.
	(call_valuei_pcrel): Add condition for SH2A target.
	(call_value): Likewise.
	* config/sh/sh-protos.h (sh_cfun_resbank_handler_p): Declare.
	(sh2a_get_function_vector_number): Likewise.
	(sh2a_is_function_vector_call): Likewise.
	* doc/extend.texi: Document TBR relative addressing of SH2A.
	(resbank): Add description for SH2A.

	* gcc.target/sh/sh2a-resbank.c: New test.
	* gcc.target/sh/sh2a-tbr-jump.c: New test.
	* gcc.target/sh/sh2a-jsrn.c: New test.
	* gcc.target/sh/sh2a-rtsn.c: New test.


Co-Authored-By: Jayant R Sonar <jayant.sonar@kpitcummins.com>
Co-Authored-By: Naveen.H.S <naveen.hs@kpitcummins.com>

From-SVN: r133513
parent 53b308f6
2008-03-25 Anil Paranjape <anil.paranjape@kpitcummins.com>
Jayant Sonar <Jayant.sonar@kpitcummins.com>
Naveen.H.S <naveen.hs@kpitcummins.com>
* config/sh/sh.c (SH_ATTRIBUTES): Define.
(SYMBOL_FLAG_FUNCVEC_FUNCTION): Define.
(print_operand): Handle resbank in %@ operand code.
(sh_encode_section_info): New.
(push_regs): Add conditions for resbank.
(sh_expand_epilogue): Likewise.
(sh_insert_attributes): Likewise.
(sh_attribute_table): Likewise.
(sh_handle_resbank_handler_attribute): New.
(sh2a_handle_function_vector_handler_attribute): New.
(sh2a_is_function_vector_call): New.
(sh2a_get_function_vector_number): New.
(sh2a_function_vector_p): New.
(sh_cfun_resbank_handler_p): New.
* config/sh/sh.md (calli): Emit jsr/n if possible.
(calli_tbr_rel): New.
(calli_pcrel): Emit jsr/n if possible.
(return_i): Emit rts/n if possible.
(call_valuei_tbr_rel): New.
(call_valuei_pcrel): Add condition for SH2A target.
(call_value): Likewise.
* config/sh/sh-protos.h (sh_cfun_resbank_handler_p): Declare.
(sh2a_get_function_vector_number): Likewise.
(sh2a_is_function_vector_call): Likewise.
* doc/extend.texi: Document TBR relative addressing of SH2A.
(resbank): Add description for SH2A.
2008-03-24 Richard Guenther <rguenther@suse.de>
PR c/22371
......
......@@ -134,6 +134,7 @@ extern int initial_elimination_offset (int, int);
extern int fldi_ok (void);
extern int sh_hard_regno_rename_ok (unsigned int, unsigned int);
extern int sh_cfun_interrupt_handler_p (void);
extern int sh_cfun_resbank_handler_p (void);
extern int sh_attr_renesas_p (const_tree);
extern int sh_cfun_attr_renesas_p (void);
extern void sh_initialize_trampoline (rtx, rtx, rtx);
......@@ -170,6 +171,8 @@ struct secondary_reload_info;
extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class,
enum machine_mode,
struct secondary_reload_info *);
extern int sh2a_get_function_vector_number (rtx);
extern int sh2a_is_function_vector_call (rtx);
#endif /* ! GCC_SH_PROTOS_H */
......
......@@ -7443,7 +7443,14 @@ label:
(use (reg:PSI FPSCR_REG))
(clobber (reg:SI PR_REG))]
"TARGET_SH1"
"jsr @%0%#"
"*
{
if (TARGET_SH2A && (dbr_sequence_length () == 0))
return \"jsr/n\\t@%0\";
else
return \"jsr\\t@%0%#\";
}"
[(set_attr "type" "call")
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
......@@ -7451,6 +7458,31 @@ label:
(set_attr "needs_delay_slot" "yes")
(set_attr "fp_set" "unknown")])
;; This is TBR relative jump instruction for SH2A architecture.
;; Its use is enabled assigning an attribute "function_vector"
;; and the vector number to a function during its declaration.
(define_insn "calli_tbr_rel"
[(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
(match_operand 1 "" ""))
(use (reg:PSI FPSCR_REG))
(clobber (reg:SI PR_REG))]
"TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
"*
{
unsigned HOST_WIDE_INT vect_num;
vect_num = sh2a_get_function_vector_number (operands[0]);
operands[2] = GEN_INT (vect_num * 4);
return \"jsr/n\\t@@(%O2,tbr)\";
}"
[(set_attr "type" "call")
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
(set_attr "needs_delay_slot" "no")
(set_attr "fp_set" "unknown")])
;; This is a pc-rel call, using bsrf, for use with PIC.
(define_insn "calli_pcrel"
......@@ -7546,7 +7578,13 @@ label:
(use (reg:PSI FPSCR_REG))
(clobber (reg:SI PR_REG))]
"TARGET_SH1"
"jsr @%1%#"
"*
{
if (TARGET_SH2A && (dbr_sequence_length () == 0))
return \"jsr/n\\t@%1\";
else
return \"jsr\\t@%1%#\";
}"
[(set_attr "type" "call")
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
......@@ -7554,6 +7592,32 @@ label:
(set_attr "needs_delay_slot" "yes")
(set_attr "fp_set" "unknown")])
;; This is TBR relative jump instruction for SH2A architecture.
;; Its use is enabled assigning an attribute "function_vector"
;; and the vector number to a function during its declaration.
(define_insn "call_valuei_tbr_rel"
[(set (match_operand 0 "" "=rf")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
(match_operand 2 "" "")))
(use (reg:PSI FPSCR_REG))
(clobber (reg:SI PR_REG))]
"TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
"*
{
unsigned HOST_WIDE_INT vect_num;
vect_num = sh2a_get_function_vector_number (operands[1]);
operands[3] = GEN_INT (vect_num * 4);
return \"jsr/n\\t@@(%O3,tbr)\";
}"
[(set_attr "type" "call")
(set (attr "fp_mode")
(if_then_else (eq_attr "fpu_single" "yes")
(const_string "single") (const_string "double")))
(set_attr "needs_delay_slot" "no")
(set_attr "fp_set" "unknown")])
(define_insn "call_valuei_pcrel"
[(set (match_operand 0 "" "=rf")
(call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
......@@ -7715,6 +7779,17 @@ label:
emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
XEXP (operands[0], 0) = reg;
}
if (!flag_pic && TARGET_SH2A
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
{
if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
{
emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
operands[1]));
DONE;
}
}
if (flag_pic && TARGET_SH2
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
......@@ -7898,6 +7973,17 @@ label:
emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
XEXP (operands[1], 0) = reg;
}
if (!flag_pic && TARGET_SH2A
&& GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{
if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
{
emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
XEXP (operands[1], 0), operands[2]));
DONE;
}
}
if (flag_pic && TARGET_SH2
&& GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
......@@ -9262,7 +9348,14 @@ mov.l\\t1f,r0\\n\\
&& reload_completed
&& lookup_attribute (\"trap_exit\",
DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
"%@ %#"
"*
{
if (TARGET_SH2A && (dbr_sequence_length () == 0)
&& !current_function_interrupt)
return \"rts/n\";
else
return \"%@ %#\";
}"
[(set_attr "type" "return")
(set_attr "needs_delay_slot" "yes")])
......
......@@ -2299,16 +2299,33 @@ is used. @xref{C Dialect Options,,Options
Controlling C Dialect}.
@item function_vector
@cindex calling functions through the function vector on H8/300, M16C, and M32C processors
@cindex calling functions through the function vector on H8/300, M16C, M32C and SH2A 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;
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.
In SH2A target, this attribute declares a function to be called using the
TBR relative addressing mode. The argument to this attribute is the entry
number of the same function in a vector table containing all the TBR
relative addressable functions. For the successful jump, register TBR
should contain the start address of this TBR relative vector table.
In the startup routine of the user application, user needs to care of this
TBR register initialization. The TBR relative vector table can have at
max 256 function entries. The jumps to these functions will be generated
using a SH2A specific, non delayed branch instruction JSR/N @@(disp8,TBR).
You must use GAS and GLD from GNU binutils version 2.7 or later for
this attribute to work correctly.
Please refer the example of M16C target, to see the use of this
attribute while declaring a function,
In an application, for a function being called once, this attribute will
save at least 8 bytes of code; and if other successive calls are being
made to the same function, it will save 2 bytes of code per each of these
calls.
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
......@@ -2722,6 +2739,19 @@ number of registers available if used in conjunction with the
attribute is incompatible with nested functions; this is considered a
hard error.
@item resbank
@cindex @code{resbank} attribute
On the SH2A target, this attribute enables the high-speed register
saving and restoration using a register bank for @code{interrupt_handler}
routines. Saving to the bank is performed automatcially after the CPU
accepts an interrupt that uses a register bank.
The nineteen 32-bit registers comprising general register R0 to R14,
control register GBR, and system registers MACH, MACL, and PR and the
vector table address offset are saved into a register bank. Register
banks are stacked in first-in last-out (FILO) sequence. Restoration
from the bank is executed by issuing a RESBANK instruction.
@item returns_twice
@cindex @code{returns_twice} attribute
The @code{returns_twice} attribute tells the compiler that a function may
......
2008-03-25 Anil Paranjape <anil.paranjape@kpitcummins.com>
Jayant Sonar <Jayant.sonar@kpitcummins.com>
Naveen.H.S <naveen.hs@kpitcummins.com>
* gcc.target/sh/sh2a-resbank.c: New test.
* gcc.target/sh/sh2a-tbr-jump.c: New test.
* gcc.target/sh/sh2a-jsrn.c: New test.
* gcc.target/sh/sh2a-rtsn.c: New test.
2008-03-25 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/sse-17.c: Include sse2-check.h.
/* Testcase to check generation of a SH2A specific instruction for
'JSR/N @Rm'. */
/* { dg-do assemble {target sh*-*-*}} */
/* { dg-options "-O0" } */
/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */
/* { dg-final { scan-assembler "jsr/n"} } */
void foo(void)
{
}
void bar()
{
foo();
}
/* Test for resbank attribute. */
/* { dg-do assemble {target sh*-*-*}} */
/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */
/* { dg-final { scan-assembler "resbank" } } */
extern void bar(void);
void foo(void) __attribute__((interrupt_handler, resbank));
void foo(void)
{
bar();
}
/* Testcase to check generation of a SH2A specific instruction for
'RTS/N'. */
/* { dg-do assemble {target sh*-*-*}} */
/* { dg-options "-O0" } */
/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */
/* { dg-final { scan-assembler "rts/n"} } */
void
bar (void)
{
}
/* Testcase to check generation of a SH2A specific,
TBR relative jump instruction - 'JSR @@(disp8,TBR)'. */
/* { dg-do assemble {target sh*-*-*}} */
/* { dg-options "" } */
/* { dg-skip-if "" { "sh*-*-*" } "*" "-m2a -m2a-nofpu -m2a-single -m2a-single-only" } */
/* { dg-final { scan-assembler-times "jsr/n\\t@@\\(40,tbr\\)" 1} } */
/* { dg-final { scan-assembler-times "jsr/n\\t@@\\(72,tbr\\)" 1} } */
extern void foo1 (void) __attribute__ ((function_vector(10)));
extern void foo2 (void);
extern int bar1 (void) __attribute__ ((function_vector(18)));
extern int bar2 (void);
int
bar()
{
foo1();
foo2();
bar1();
bar2();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment