public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch, microblaze]: Added fast_interrupt controller
@ 2013-02-11  6:39 David Holsgrove
  2013-02-26 18:12 ` Michael Eager
  0 siblings, 1 reply; 4+ messages in thread
From: David Holsgrove @ 2013-02-11  6:39 UTC (permalink / raw)
  To: gcc-patches
  Cc: Michael Eager (eager@eagercon.com),
	John Williams, Edgar E. Iglesias (edgar.iglesias@gmail.com),
	Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala, Tom Shui

[-- Attachment #1: Type: text/plain, Size: 859 bytes --]

Added fast_interrupt controller

Changelog

2013-02-11  Nagaraju Mekala <nmekala@xilinx.com>

  * config/microblaze/microblaze-protos.h: microblaze_is_fast_interrupt.
  * config/microblaze/microblaze.c (microblaze_attribute_table): Add
     microblaze_is_fast_interrupt.
     (microblaze_fast_interrupt_function_p): New function.
     (microblaze_is_fast_interrupt check): New function.
     (microblaze_must_save_register): Account for fast_interrupt.
     (save_restore_insns): Likewise.
     (compute_frame_size): Likewise.
     (microblaze_globalize_label): Add FAST_INTERRUPT_NAME.
  * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME as
     fast_interrupt.
  * config/microblaze/microblaze.md (movsi_status): Can be
     fast_interrupt
     (return): Add microblaze_is_fast_interrupt.
     (return_internal): Likewise.


[-- Attachment #2: 0008-Gcc-Added-fast_interrupt-controller.patch --]
[-- Type: application/octet-stream, Size: 9007 bytes --]

From 466205ab6acad62cf6ac66e3f29b4b0f1e9271b8 Mon Sep 17 00:00:00 2001
From: nagaraju <nmekala@xilix.com>
Date: Tue, 28 Feb 2012 15:32:29 +0530
Subject: [PATCH] Gcc: Added fast_interrupt controller

Changelog

2013-02-11  Nagaraju Mekala <nmekala@xilinx.com>

  *  gcc/config/microblaze/microblaze-protos.h: microblaze_is_fast_interrupt.
  *  gcc/config/microblaze/microblaze.c (microblaze_attribute_table): Add
     microblaze_is_fast_interrupt.
     (microblaze_fast_interrupt_function_p): New function.
     (microblaze_is_fast_interrupt check): New function.
     (microblaze_must_save_register): Account for fast_interrupt.
     (save_restore_insns): Likewise.
     (compute_frame_size): Likewise.
     (microblaze_globalize_label): Add FAST_INTERRUPT_NAME.
  *  gcc/config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME as
     _fast_interrupt.
  *  gcc/config/microblaze/microblaze.md (movsi_status): Can be fast_interrupt
     (return): Add microblaze_is_fast_interrupt.
     (return_internal): Likewise.

Signed-off-by: Nagaraju Mekala <nmekala@xilinx.com>
Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
---
 gcc/config/microblaze/microblaze-protos.h |    1 +
 gcc/config/microblaze/microblaze.c        |   51 +++++++++++++++++++++++++----
 gcc/config/microblaze/microblaze.h        |    2 +
 gcc/config/microblaze/microblaze.md       |    6 ++--
 4 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index 44740f3..1915525 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -40,6 +40,7 @@ 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_fast_interrupt (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 8819655..0fa4013 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -198,6 +198,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[] = {
@@ -205,6 +206,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,
@@ -1503,6 +1506,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.  */
 
@@ -1527,6 +1542,12 @@ microblaze_is_interrupt_handler (void)
   return interrupt_handler;
 }
 
+int
+microblaze_is_fast_interrupt (void)
+{
+  return fast_interrupt;
+}
+
 /* Determine of register must be saved/restored in call.  */
 static int
 microblaze_must_save_register (int regno)
@@ -1545,7 +1566,7 @@ microblaze_must_save_register (int regno)
     {
       if (regno == MB_ABI_SUB_RETURN_ADDR_REGNUM)
 	return 1;
-      if ((interrupt_handler || save_volatiles) &&
+      if ((fast_interrupt || interrupt_handler || save_volatiles) &&
 	  (regno >= 3 && regno <= 12))
 	return 1;
     }
@@ -1559,6 +1580,13 @@ microblaze_must_save_register (int regno)
 	return 1;
     }
 
+  if (fast_interrupt)
+    {
+      if (df_regs_ever_live_p (regno)
+	  || regno == MB_ABI_MSR_SAVE_REG)
+	return 1;
+    }
+
   if (save_volatiles)
     {
       if (df_regs_ever_live_p (regno)
@@ -1628,6 +1656,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;
@@ -1661,7 +1691,7 @@ compute_frame_size (HOST_WIDE_INT size)
   total_size += gp_reg_size;
 
   /* Add 4 bytes for MSR.  */
-  if (interrupt_handler)
+  if (interrupt_handler || fast_interrupt)
     total_size += 4;
 
   /* No space to be allocated for link register in leaf functions with no other
@@ -2153,7 +2183,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 (interrupt_handler || fast_interrupt)
     {
       isr_mem_rtx = gen_rtx_MEM (SImode,
 				 gen_rtx_PLUS (Pmode, base_reg_rtx,
@@ -2167,7 +2197,7 @@ save_restore_insns (int prologue)
       isr_msr_rtx = gen_rtx_REG (SImode, ST_REG);
     }
 
-  if (interrupt_handler && !prologue)
+  if ((interrupt_handler && !prologue) ||( fast_interrupt && !prologue) )
     {
       emit_move_insn (isr_reg_rtx, isr_mem_rtx);
       emit_move_insn (isr_msr_rtx, isr_reg_rtx);
@@ -2187,7 +2217,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 (interrupt_handler || save_volatiles || fast_interrupt)
 	    /* Do not optimize in flow analysis.  */
 	    MEM_VOLATILE_P (mem_rtx) = 1;
 
@@ -2205,7 +2235,7 @@ save_restore_insns (int prologue)
 	}
     }
 
-  if (interrupt_handler && prologue)
+  if ((interrupt_handler && prologue) || (fast_interrupt && prologue))
     {
       emit_move_insn (isr_reg_rtx, isr_msr_rtx);
       emit_move_insn (isr_mem_rtx, isr_reg_rtx);
@@ -2235,10 +2265,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 (!interrupt_handler || !fast_interrupt)
 	ASM_OUTPUT_TYPE_DIRECTIVE (file, fnname, "function");
     }
 
@@ -2595,6 +2627,11 @@ microblaze_globalize_label (FILE * stream, const char *name)
       fputs (INTERRUPT_HANDLER_NAME, stream);
       fputs ("\n\t.globl\t", stream);
     }
+  if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME))
+    {
+      fputs (FAST_INTERRUPT_NAME, stream);
+      fputs ("\n\t.globl\t", stream);
+    }
   assemble_name (stream, name);
   fputs ("\n", stream);
 }
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 76ee811..814e8ab 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -760,9 +760,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 2e636c0..6933546 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"
+  "interrupt_handler || fast_interrupt"
   "@
 	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_handler () || microblaze_is_fast_interrupt())
         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_handler () || microblaze_is_fast_interrupt())
         return "rtid\tr14,0 \;%#";
     else
         return "rtsd\tr15,8 \;%#";
-- 
1.7.3.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch, microblaze]: Added fast_interrupt controller
  2013-02-11  6:39 [Patch, microblaze]: Added fast_interrupt controller David Holsgrove
@ 2013-02-26 18:12 ` Michael Eager
  2013-03-05 15:10   ` David Holsgrove
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Eager @ 2013-02-26 18:12 UTC (permalink / raw)
  To: David Holsgrove
  Cc: gcc-patches, Michael Eager (eager@eagercon.com),
	John Williams, Edgar E. Iglesias (edgar.iglesias@gmail.com),
	Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala, Tom Shui

On 02/10/2013 10:39 PM, David Holsgrove wrote:
> Added fast_interrupt controller
>
> Changelog
>
> 2013-02-11  Nagaraju Mekala <nmekala@xilinx.com>
>
>    * config/microblaze/microblaze-protos.h: microblaze_is_fast_interrupt.
>    * config/microblaze/microblaze.c (microblaze_attribute_table): Add
>       microblaze_is_fast_interrupt.
>       (microblaze_fast_interrupt_function_p): New function.
>       (microblaze_is_fast_interrupt check): New function.
>       (microblaze_must_save_register): Account for fast_interrupt.
>       (save_restore_insns): Likewise.
>       (compute_frame_size): Likewise.
>       (microblaze_globalize_label): Add FAST_INTERRUPT_NAME.
>    * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME as
>       fast_interrupt.
>    * config/microblaze/microblaze.md (movsi_status): Can be
>       fast_interrupt
>       (return): Add microblaze_is_fast_interrupt.
>       (return_internal): Likewise.

+int
+microblaze_is_fast_interrupt (void)
+{
+  return fast_interrupt;
+}

+  if (fast_interrupt)
+    {

Use wrapper functions consistently.  Either reference the flag everywhere
or use the wrapper everywhere.

+  if (interrupt_handler || fast_interrupt)

+  if (microblaze_is_interrupt_handler () || microblaze_is_fast_interrupt())

There are many places in the patch where both interrupt_handler and fast_interrupt
are tested.  These can be eliminated by setting the interrupt_handler flag when
you see fast_interrupt and checking for the correct registers to be saved in
microblaze_must_save_register().

+  if ((interrupt_handler && !prologue) ||( fast_interrupt && !prologue) )

+  if ((interrupt_handler && prologue) || (fast_interrupt && prologue))

Refactor.  Fix spacing around parens.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [Patch, microblaze]: Added fast_interrupt controller
  2013-02-26 18:12 ` Michael Eager
@ 2013-03-05 15:10   ` David Holsgrove
  2013-03-05 19:36     ` Michael Eager
  0 siblings, 1 reply; 4+ messages in thread
From: David Holsgrove @ 2013-03-05 15:10 UTC (permalink / raw)
  To: Michael Eager
  Cc: gcc-patches, Michael Eager (eager@eagercon.com),
	John Williams, Edgar E. Iglesias (edgar.iglesias@gmail.com),
	Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala, Tom Shui

[-- Attachment #1: Type: text/plain, Size: 4010 bytes --]

Hi Michael,

> -----Original Message-----
> From: Michael Eager [mailto:eager@eagerm.com]
> Sent: Wednesday, 27 February 2013 4:12 am
> To: David Holsgrove
> Cc: gcc-patches@gcc.gnu.org; Michael Eager (eager@eagercon.com); John
> Williams; Edgar E. Iglesias (edgar.iglesias@gmail.com); Vinod Kathail; Vidhumouli
> Hunsigida; Nagaraju Mekala; Tom Shui
> Subject: Re: [Patch, microblaze]: Added fast_interrupt controller
> 
> On 02/10/2013 10:39 PM, David Holsgrove wrote:
> > Added fast_interrupt controller
> >
> > Changelog
> >
> > 2013-02-11  Nagaraju Mekala <nmekala@xilinx.com>
> >
> >    * config/microblaze/microblaze-protos.h: microblaze_is_fast_interrupt.
> >    * config/microblaze/microblaze.c (microblaze_attribute_table): Add
> >       microblaze_is_fast_interrupt.
> >       (microblaze_fast_interrupt_function_p): New function.
> >       (microblaze_is_fast_interrupt check): New function.
> >       (microblaze_must_save_register): Account for fast_interrupt.
> >       (save_restore_insns): Likewise.
> >       (compute_frame_size): Likewise.
> >       (microblaze_globalize_label): Add FAST_INTERRUPT_NAME.
> >    * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME as
> >       fast_interrupt.
> >    * config/microblaze/microblaze.md (movsi_status): Can be
> >       fast_interrupt
> >       (return): Add microblaze_is_fast_interrupt.
> >       (return_internal): Likewise.
> 
> +int
> +microblaze_is_fast_interrupt (void)
> +{
> +  return fast_interrupt;
> +}
> 
> +  if (fast_interrupt)
> +    {
> 
> Use wrapper functions consistently.  Either reference the flag everywhere
> or use the wrapper everywhere.

I've repurposed the existing 'microblaze_is_interrupt_handler' wrapper, (which was
only used in the machine description), to be 'microblaze_is_interrupt_variant' - true
if the function's attribute is either interrupt_handler or fast_interrupt.

> 
> +  if (interrupt_handler || fast_interrupt)
> 
> +  if (microblaze_is_interrupt_handler () || microblaze_is_fast_interrupt())
> 
> There are many places in the patch where both interrupt_handler and
> fast_interrupt
> are tested.  These can be eliminated by setting the interrupt_handler flag when
> you see fast_interrupt and checking for the correct registers to be saved in
> microblaze_must_save_register().

I've used this microblaze_is_interrupt_variant wrapper throughout, checking
specifically for the interrupt_handler or fast_interrupt flag only where it was
necessary to handle them differently.

Please let me know if the patch attached is acceptable, or if you would prefer
I refactor all the existing interrupt_handler functionality to accommodate the
fast_interrupt.

Updated Changelog;

2013-03-05  David Holsgrove <david.holsgrove@xilinx.com>

  *  gcc/config/microblaze/microblaze-protos.h: Rename
     microblaze_is_interrupt_handler to microblaze_is_interrupt_variant.
  *  gcc/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.
  *  gcc/config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME.
  *  gcc/config/microblaze/microblaze.md: Use wrapper
     microblaze_is_interrupt_variant.


thanks again for the reviews,
David

> 
> +  if ((interrupt_handler && !prologue) ||( fast_interrupt && !prologue) )
> 
> +  if ((interrupt_handler && prologue) || (fast_interrupt && prologue))
> 
> Refactor.  Fix spacing around parens.
> 
> --
> Michael Eager	 eager@eagercon.com
> 1960 Park Blvd., Palo Alto, CA 94306  650-325-8077




[-- Attachment #2: 0002-Gcc-Added-fast_interrupt-controller.patch --]
[-- Type: application/octet-stream, Size: 9687 bytes --]

From 23ab486e7607eeca17d73e2b3e36c21ebca75b64 Mon Sep 17 00:00:00 2001
From: nagaraju <nmekala@xilix.com>
Date: Tue, 28 Feb 2012 15:32:29 +0530
Subject: [PATCH] Gcc: Added fast_interrupt controller

Changelog

2013-03-05  David Holsgrove <david.holsgrove@xilinx.com>

  *  gcc/config/microblaze/microblaze-protos.h: Rename
     microblaze_is_interrupt_handler to microblaze_is_interrupt_variant.
  *  gcc/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.
  *  gcc/config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME.
  *  gcc/config/microblaze/microblaze.md: Use wrapper
     microblaze_is_interrupt_variant.

Signed-off-by: Nagaraju Mekala <nmekala@xilinx.com>
Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
---
 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 ++--
 4 files changed, 46 insertions(+), 20 deletions(-)

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..a54e197 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 \;%#";
-- 
1.7.0.4


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch, microblaze]: Added fast_interrupt controller
  2013-03-05 15:10   ` David Holsgrove
@ 2013-03-05 19:36     ` Michael Eager
  0 siblings, 0 replies; 4+ messages in thread
From: Michael Eager @ 2013-03-05 19:36 UTC (permalink / raw)
  To: David Holsgrove
  Cc: Michael Eager, gcc-patches, John Williams,
	Edgar E. Iglesias (edgar.iglesias@gmail.com),
	Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala, Tom Shui

On 03/05/2013 07:09 AM, David Holsgrove wrote:
> Hi Michael,
>
>> -----Original Message-----
>> From: Michael Eager [mailto:eager@eagerm.com]
>> Sent: Wednesday, 27 February 2013 4:12 am
>> To: David Holsgrove
>> Cc: gcc-patches@gcc.gnu.org; Michael Eager (eager@eagercon.com); John
>> Williams; Edgar E. Iglesias (edgar.iglesias@gmail.com); Vinod Kathail; Vidhumouli
>> Hunsigida; Nagaraju Mekala; Tom Shui
>> Subject: Re: [Patch, microblaze]: Added fast_interrupt controller
>>
>> On 02/10/2013 10:39 PM, David Holsgrove wrote:
>>> Added fast_interrupt controller
>>>
>>> Changelog
>>>
>>> 2013-02-11  Nagaraju Mekala <nmekala@xilinx.com>
>>>
>>>     * config/microblaze/microblaze-protos.h: microblaze_is_fast_interrupt.
>>>     * config/microblaze/microblaze.c (microblaze_attribute_table): Add
>>>        microblaze_is_fast_interrupt.
>>>        (microblaze_fast_interrupt_function_p): New function.
>>>        (microblaze_is_fast_interrupt check): New function.
>>>        (microblaze_must_save_register): Account for fast_interrupt.
>>>        (save_restore_insns): Likewise.
>>>        (compute_frame_size): Likewise.
>>>        (microblaze_globalize_label): Add FAST_INTERRUPT_NAME.
>>>     * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME as
>>>        fast_interrupt.
>>>     * config/microblaze/microblaze.md (movsi_status): Can be
>>>        fast_interrupt
>>>        (return): Add microblaze_is_fast_interrupt.
>>>        (return_internal): Likewise.
>>
>> +int
>> +microblaze_is_fast_interrupt (void)
>> +{
>> +  return fast_interrupt;
>> +}
>>
>> +  if (fast_interrupt)
>> +    {
>>
>> Use wrapper functions consistently.  Either reference the flag everywhere
>> or use the wrapper everywhere.
>
> I've repurposed the existing 'microblaze_is_interrupt_handler' wrapper, (which was
> only used in the machine description), to be 'microblaze_is_interrupt_variant' - true
> if the function's attribute is either interrupt_handler or fast_interrupt.
>
>>
>> +  if (interrupt_handler || fast_interrupt)
>>
>> +  if (microblaze_is_interrupt_handler () || microblaze_is_fast_interrupt())
>>
>> There are many places in the patch where both interrupt_handler and
>> fast_interrupt
>> are tested.  These can be eliminated by setting the interrupt_handler flag when
>> you see fast_interrupt and checking for the correct registers to be saved in
>> microblaze_must_save_register().
>
> I've used this microblaze_is_interrupt_variant wrapper throughout, checking
> specifically for the interrupt_handler or fast_interrupt flag only where it was
> necessary to handle them differently.
>
> Please let me know if the patch attached is acceptable, or if you would prefer
> I refactor all the existing interrupt_handler functionality to accommodate the
> fast_interrupt.
>
> Updated Changelog;
>
> 2013-03-05  David Holsgrove <david.holsgrove@xilinx.com>
>
>    *  gcc/config/microblaze/microblaze-protos.h: Rename
>       microblaze_is_interrupt_handler to microblaze_is_interrupt_variant.
>    *  gcc/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.
>    *  gcc/config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME.
>    *  gcc/config/microblaze/microblaze.md: Use wrapper
>       microblaze_is_interrupt_variant.
>
>
> thanks again for the reviews,
> David
>
>>
>> +  if ((interrupt_handler && !prologue) ||( fast_interrupt && !prologue) )
>>
>> +  if ((interrupt_handler && prologue) || (fast_interrupt && prologue))
>>
>> Refactor.  Fix spacing around parens.


Committed revision 196474.



-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-03-05 19:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-11  6:39 [Patch, microblaze]: Added fast_interrupt controller David Holsgrove
2013-02-26 18:12 ` Michael Eager
2013-03-05 15:10   ` David Holsgrove
2013-03-05 19:36     ` Michael Eager

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).