From ee61ea3844e8deee83cee22e037b15339f823171 Mon Sep 17 00:00:00 2001 From: David Holsgrove Date: Tue, 5 Mar 2013 19:34:25 +0000 Subject: [PATCH] Add fast interrupt. * config/microblaze/microblaze-protos.h: Rename microblaze_is_interrupt_handler to microblaze_is_interrupt_variant. * config/microblaze/microblaze.c (microblaze_attribute_table): Add fast_interrupt. (microblaze_fast_interrupt_function_p): New function. (microblaze_is_interrupt_handler): Rename to microblaze_is_interrupt_variant and add fast_interrupt check. (microblaze_must_save_register): Use microblaze_is_interrupt_variant. (save_restore_insns): Likewise. (compute_frame_size): Likewise. (microblaze_function_prologue): Add FAST_INTERRUPT_NAME. (microblaze_globalize_label): Likewise. * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME. * config/microblaze/microblaze.md: Use wrapper microblaze_is_interrupt_variant. From-SVN: r196474 --- gcc/ChangeLog | 18 ++++++++++ gcc/config/microblaze/microblaze-protos.h | 2 +- gcc/config/microblaze/microblaze.c | 56 ++++++++++++++++++++++--------- gcc/config/microblaze/microblaze.h | 2 ++ gcc/config/microblaze/microblaze.md | 6 ++-- 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2be47af..453c57b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2013-03-05 David Holsgrove + + * config/microblaze/microblaze-protos.h: Rename + microblaze_is_interrupt_handler to microblaze_is_interrupt_variant. + * config/microblaze/microblaze.c (microblaze_attribute_table): Add + fast_interrupt. + (microblaze_fast_interrupt_function_p): New function. + (microblaze_is_interrupt_handler): Rename to + microblaze_is_interrupt_variant and add fast_interrupt check. + (microblaze_must_save_register): Use microblaze_is_interrupt_variant. + (save_restore_insns): Likewise. + (compute_frame_size): Likewise. + (microblaze_function_prologue): Add FAST_INTERRUPT_NAME. + (microblaze_globalize_label): Likewise. + * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME. + * config/microblaze/microblaze.md: Use wrapper + microblaze_is_interrupt_variant. + 2013-03-05 Kai Tietz * sdbout.c (sdbout_one_type): Switch to current function's section diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h index fe2ac09..e19939f 100644 --- a/gcc/config/microblaze/microblaze-protos.h +++ b/gcc/config/microblaze/microblaze-protos.h @@ -39,7 +39,7 @@ extern void print_operand (FILE *, rtx, int); extern void print_operand_address (FILE *, rtx); extern void init_cumulative_args (CUMULATIVE_ARGS *,tree, rtx); extern bool microblaze_legitimate_address_p (enum machine_mode, rtx, bool); -extern int microblaze_is_interrupt_handler (void); +extern int microblaze_is_interrupt_variant (void); extern rtx microblaze_return_addr (int, rtx); extern int simple_memory_operand (rtx, enum machine_mode); extern int double_memory_operand (rtx, enum machine_mode); diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 5286316..3a52994 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -195,6 +195,7 @@ enum reg_class microblaze_regno_to_class[] = and epilogue and use appropriate interrupt return. save_volatiles - Similar to interrupt handler, but use normal return. */ int interrupt_handler; +int fast_interrupt; int save_volatiles; const struct attribute_spec microblaze_attribute_table[] = { @@ -202,6 +203,8 @@ const struct attribute_spec microblaze_attribute_table[] = { affects_type_identity */ {"interrupt_handler", 0, 0, true, false, false, NULL, false }, + {"fast_interrupt", 0, 0, true, false, false, NULL, + false }, {"save_volatiles" , 0, 0, true, false, false, NULL, false }, { NULL, 0, 0, false, false, false, NULL, @@ -1506,6 +1509,18 @@ microblaze_interrupt_function_p (tree func) return a != NULL_TREE; } +static int +microblaze_fast_interrupt_function_p (tree func) +{ + tree a; + + if (TREE_CODE (func) != FUNCTION_DECL) + return 0; + + a = lookup_attribute ("fast_interrupt", DECL_ATTRIBUTES (func)); + return a != NULL_TREE; +} + /* Return true if FUNC is an interrupt function which uses normal return, indicated by the "save_volatiles" attribute. */ @@ -1522,12 +1537,13 @@ microblaze_save_volatiles (tree func) } /* Return whether function is tagged with 'interrupt_handler' - attribute. Return true if function should use return from - interrupt rather than normal function return. */ + or 'fast_interrupt' attribute. Return true if function + should use return from interrupt rather than normal + function return. */ int -microblaze_is_interrupt_handler (void) +microblaze_is_interrupt_variant (void) { - return interrupt_handler; + return (interrupt_handler || fast_interrupt); } /* Determine of register must be saved/restored in call. */ @@ -1548,17 +1564,18 @@ microblaze_must_save_register (int regno) { if (regno == MB_ABI_SUB_RETURN_ADDR_REGNUM) return 1; - if ((interrupt_handler || save_volatiles) && + if ((microblaze_is_interrupt_variant () || save_volatiles) && (regno >= 3 && regno <= 12)) return 1; } - if (interrupt_handler) + if (microblaze_is_interrupt_variant ()) { if (df_regs_ever_live_p (regno) || regno == MB_ABI_MSR_SAVE_REG - || regno == MB_ABI_ASM_TEMP_REGNUM - || regno == MB_ABI_EXCEPTION_RETURN_ADDR_REGNUM) + || (interrupt_handler + && (regno == MB_ABI_ASM_TEMP_REGNUM + || regno == MB_ABI_EXCEPTION_RETURN_ADDR_REGNUM))) return 1; } @@ -1631,6 +1648,8 @@ compute_frame_size (HOST_WIDE_INT size) interrupt_handler = microblaze_interrupt_function_p (current_function_decl); + fast_interrupt = + microblaze_fast_interrupt_function_p (current_function_decl); save_volatiles = microblaze_save_volatiles (current_function_decl); gp_reg_size = 0; @@ -1664,7 +1683,7 @@ compute_frame_size (HOST_WIDE_INT size) total_size += gp_reg_size; /* Add 4 bytes for MSR. */ - if (interrupt_handler) + if (microblaze_is_interrupt_variant ()) total_size += 4; /* No space to be allocated for link register in leaf functions with no other @@ -2156,7 +2175,7 @@ save_restore_insns (int prologue) base_reg_rtx = stack_pointer_rtx; /* For interrupt_handlers, need to save/restore the MSR. */ - if (interrupt_handler) + if (microblaze_is_interrupt_variant ()) { isr_mem_rtx = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, base_reg_rtx, @@ -2170,7 +2189,7 @@ save_restore_insns (int prologue) isr_msr_rtx = gen_rtx_REG (SImode, ST_REG); } - if (interrupt_handler && !prologue) + if (microblaze_is_interrupt_variant () && !prologue) { emit_move_insn (isr_reg_rtx, isr_mem_rtx); emit_move_insn (isr_msr_rtx, isr_reg_rtx); @@ -2190,7 +2209,7 @@ save_restore_insns (int prologue) reg_rtx = gen_rtx_REG (SImode, regno); insn = gen_rtx_PLUS (Pmode, base_reg_rtx, GEN_INT (gp_offset)); mem_rtx = gen_rtx_MEM (SImode, insn); - if (interrupt_handler || save_volatiles) + if (microblaze_is_interrupt_variant () || save_volatiles) /* Do not optimize in flow analysis. */ MEM_VOLATILE_P (mem_rtx) = 1; @@ -2208,7 +2227,7 @@ save_restore_insns (int prologue) } } - if (interrupt_handler && prologue) + if (microblaze_is_interrupt_variant () && prologue) { emit_move_insn (isr_reg_rtx, isr_msr_rtx); emit_move_insn (isr_mem_rtx, isr_reg_rtx); @@ -2238,10 +2257,12 @@ microblaze_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) fputs ("\t.ent\t", file); if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname)) fputs ("_interrupt_handler", file); + else if (fast_interrupt && strcmp (FAST_INTERRUPT_NAME, fnname)) + fputs ("_fast_interrupt", file); else assemble_name (file, fnname); fputs ("\n", file); - if (!interrupt_handler) + if (!microblaze_is_interrupt_variant ()) ASM_OUTPUT_TYPE_DIRECTIVE (file, fnname, "function"); } @@ -2593,9 +2614,12 @@ static void microblaze_globalize_label (FILE * stream, const char *name) { fputs ("\t.globl\t", stream); - if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME)) + if (microblaze_is_interrupt_variant ()) { - fputs (INTERRUPT_HANDLER_NAME, stream); + if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME)) + fputs (INTERRUPT_HANDLER_NAME, stream); + else if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME)) + fputs (FAST_INTERRUPT_NAME, stream); fputs ("\n\t.globl\t", stream); } assemble_name (stream, name); diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h index c726978..8fbe5bf 100644 --- a/gcc/config/microblaze/microblaze.h +++ b/gcc/config/microblaze/microblaze.h @@ -756,9 +756,11 @@ do { \ /* Handle interrupt attribute. */ extern int interrupt_handler; +extern int fast_interrupt; extern int save_volatiles; #define INTERRUPT_HANDLER_NAME "_interrupt_handler" +#define FAST_INTERRUPT_NAME "_fast_interrupt" /* The following #defines are used in the headers files. Always retain these. */ diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md index 78c033e..0285787 100644 --- a/gcc/config/microblaze/microblaze.md +++ b/gcc/config/microblaze/microblaze.md @@ -961,7 +961,7 @@ (define_insn "movsi_status" [(set (match_operand:SI 0 "register_operand" "=d,d,z") (match_operand:SI 1 "register_operand" "z,d,d"))] - "interrupt_handler" + "microblaze_is_interrupt_variant ()" "@ mfs\t%0,%1 #mfs addk\t%0,%1,r0 #add movsi @@ -1918,7 +1918,7 @@ [(any_return)] "" { - if (microblaze_is_interrupt_handler ()) + if (microblaze_is_interrupt_variant ()) return "rtid\tr14, 0\;%#"; else return "rtsd\tr15, 8\;%#"; @@ -1935,7 +1935,7 @@ (use (match_operand:SI 0 "register_operand" ""))] "" { - if (microblaze_is_interrupt_handler ()) + if (microblaze_is_interrupt_variant ()) return "rtid\tr14,0 \;%#"; else return "rtsd\tr15,8 \;%#"; -- 2.7.4