public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [Patch,Microblaze]: Added Break Handler Support
       [not found] <345d2b49-c710-4795-924b-217a5221921c@CO9EHSMHS012.ehs.local>
@ 2014-05-06 15:00 ` Michael Eager
       [not found] ` <5368F2DA.9090509@eagercon.com>
  1 sibling, 0 replies; 9+ messages in thread
From: Michael Eager @ 2014-05-06 15:00 UTC (permalink / raw)
  To: Ajit Kumar Agarwal, gcc-patches
  Cc: Edgar Iglesias, John Williams, Vinod Kathail,
	Vidhumouli Hunsigida, Nagaraju Mekala

On 05/06/14 06:10, Ajit Kumar Agarwal wrote:
> Hello All:
>
> Could you please review this patch.
>
> [PATCH] Break handler is used to support a normal hardware break.
> This is similar to interrupt_handler except that RTBD should be used instead of RTID.
>
> Changelog
>
> 2014-05-06 Nagaraju <nmekala@xilinx.com>
>
> * gcc/config/microblaze/microblaze-protos.h : Declaration of microblaze_is_break_handler.
> * gcc/config/microblaze/microblaze.c :  Add functions to support break handler
> * gcc/config/microblaze/microblaze.h :  Add required defination declaration.
> * gcc/config/microblaze/microblaze.md : Add pattern for generating instruction rtbd.

Please follow conventions for ChangeLog.  For example
   * config/microblaze/microblaze.c (microblaze_break_function_p): New.

See http://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs

Add documentation for _break_handler.

Add test case(s).

Code formatting issues:
+  a = lookup_attribute("break_handler",DECL_ATTRIBUTES (func));
Space before left paren, after comma.
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+       	fputs ("_break_handler", file);
Incorrect indent.
+    if (microblaze_is_break_handler ())
+        return "rtbd\tr16, 0\;%#";
Ditto.
+    if (microblaze_is_break_handler ())
+        return "rtbd\tr16, 0\;%#";
Ditto.


Mailing list conventions do not permit restrictive annotations.


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

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

* RE: [Patch,Microblaze]: Added Break Handler Support
       [not found] ` <5368F2DA.9090509@eagercon.com>
@ 2014-05-13  9:15   ` Ajit Kumar Agarwal
  2014-05-13 17:00     ` Michael Eager
  0 siblings, 1 reply; 9+ messages in thread
From: Ajit Kumar Agarwal @ 2014-05-13  9:15 UTC (permalink / raw)
  To: gcc-patches
  Cc: Michael Eager, Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

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

Hello Michael:

The following patch is to handle Software and Hardware breaks in Microblaze Architecture.
Deja GNU testcase does not have any regressions and the testcase attached passes through.
Review comments are incorporated.

Okay for trunk?

Thanks & Regards
Ajit

From 15dfaee8feef37430745d3dbc58f74bed876aabb Mon Sep 17 00:00:00 2001
From: Ajit Kumar Agarwal <ajitkum@xilinx.com>
Date: Tue, 13 May 2014 13:25:52 +0530
Subject: [PATCH] [Patch, microblaze] Added Break Handler support

Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
will be generating the rtbd instruction. At the call point where the software breaks are generated with
the instruction brki with register operand as r16.

2014-05-13 Ajit Agarwal <ajitkum@xilinx.com>

* config/microblaze/microblaze.c
   (microblaze_break_function_p,microblaze_is_break_handler) : New

* config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro

* config/microblaze/microblaze.md :
  Extended support for generation of brki instruction and rtbd instruction.

* config/microblaze/microblaze-protos.h
   (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.

* testsuite/gcc.target/microblaze/others/break_handler.c : New.

Signed-off-by:Nagaraju <nmekala@xilinx.com>
---
gcc/config/microblaze/microblaze-protos.h          |    4 +-
gcc/config/microblaze/microblaze.c                 |   47 +++++++++++++++++---
gcc/config/microblaze/microblaze.h                 |    2 +-
gcc/config/microblaze/microblaze.md                |   34 ++++++++++----
.../gcc.target/microblaze/others/break_handler.c   |   15 ++++++
5 files changed, 83 insertions(+), 19 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/microblaze/others/break_handler.c

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index b03e9e1..f3cc099 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -40,10 +40,12 @@ 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_variant (void);
+extern int microblaze_is_break_handler (void);
+extern int microblaze_break_function_p (tree func);
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);
-
+extern void microblaze_order_regs_for_local_alloc (void);
extern int microblaze_regno_ok_for_base_p (int, int);
extern HOST_WIDE_INT microblaze_initial_elimination_offset (int, int);
extern void microblaze_declare_object (FILE *, const char *, const char *,
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index ba8109b..fc458a5 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -209,6 +209,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 break_handler;
int fast_interrupt;
int save_volatiles;

@@ -217,6 +218,8 @@ const struct attribute_spec microblaze_attribute_table[] = {
      affects_type_identity */
   {"interrupt_handler", 0,       0,     true,    false,   false,        NULL,
    false },
+  {"break_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,
@@ -1866,7 +1869,18 @@ microblaze_fast_interrupt_function_p (tree func)
   a = lookup_attribute ("fast_interrupt", DECL_ATTRIBUTES (func));
   return a != NULL_TREE;
}
+int
+microblaze_break_function_p (tree func)
+{
+  tree a;
+  if (!func) 
+    return 0;
+  if (TREE_CODE (func) != FUNCTION_DECL)
+    return 0;

+  a = lookup_attribute ("break_handler", 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.  */

@@ -1891,6 +1905,13 @@ microblaze_is_interrupt_variant (void)
{
   return (interrupt_handler || fast_interrupt);
}
+int 
+microblaze_is_break_handler (void) 
+{ 
+  return break_handler; 
+} 
+
+ 
 
 /* Determine of register must be saved/restored in call.  */
static int
@@ -1994,9 +2015,14 @@ compute_frame_size (HOST_WIDE_INT size)

   interrupt_handler =
     microblaze_interrupt_function_p (current_function_decl);
+  break_handler = 
+    microblaze_break_function_p (current_function_decl); 
+
   fast_interrupt =
     microblaze_fast_interrupt_function_p (current_function_decl);
   save_volatiles = microblaze_save_volatiles (current_function_decl);
+  if (break_handler)
+    interrupt_handler = break_handler;

   gp_reg_size = 0;
   mask = 0;
@@ -2641,9 +2667,11 @@ 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);
+        fputs ("_interrupt_handler", file);
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname)) 
+          fputs ("_break_handler", file); 
       else if (fast_interrupt && strcmp (FAST_INTERRUPT_NAME, fnname))
-    fputs ("_fast_interrupt", file);
+        fputs ("_fast_interrupt", file);
       else
    assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2654,9 +2682,10 @@ microblaze_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
   assemble_name (file, fnname);
   fputs (":\n", file);

-  if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname))
+  if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname) && !break_handler)
     fputs ("_interrupt_handler:\n", file);
-
+  if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+    fputs ("_break_handler:\n", file);
   if (!flag_inhibit_size_directive)
     {
       /* .frame FRAMEREG, FRAMESIZE, RETREG.  */
@@ -2791,6 +2820,7 @@ microblaze_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = fsiz;

+
   /* If this function is a varargs function, store any registers that
      would normally hold arguments ($5 - $10) on the stack.  */
   if (((TYPE_ARG_TYPES (fntype) != 0
@@ -2892,8 +2922,10 @@ microblaze_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
   if (!flag_inhibit_size_directive)
     {
       fputs ("\t.end\t", file);
-      if (interrupt_handler)
+      if (interrupt_handler && !break_handler)
    fputs ("_interrupt_handler", file);
+      else if (break_handler)
+        fputs ("_break_handler", file);
       else
    assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2934,7 +2966,7 @@ microblaze_expand_epilogue (void)
          sequence of load-followed by a use (in rtsd) in every prologue. Saves 
          a load-use stall cycle  :)   This is also important to handle alloca. 
          (See comments for if (frame_pointer_needed) below.  */
-
+      
       if (!crtl->is_leaf || interrupt_handler)
    {
      mem_rtx =
@@ -3007,6 +3039,8 @@ microblaze_globalize_label (FILE * stream, const char *name)
     {
       if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME))
         fputs (INTERRUPT_HANDLER_NAME, stream);
+      else if (break_handler && strcmp (name, BREAK_HANDLER_NAME)) 
+        fputs (BREAK_HANDLER_NAME, stream); 
       else if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME))
         fputs (FAST_INTERRUPT_NAME, stream);
       fputs ("\n\t.globl\t", stream);
@@ -3247,7 +3281,6 @@ microblaze_expand_shift (rtx operands[])

   return 0;
}
-
/* Return an RTX indicating where the return address to the
    calling function can be found.  */
rtx
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 58d8895..b979206 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -263,7 +263,6 @@ extern enum pipeline_type microblaze_pipe;
  1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,              \
   1, 1, 1, 1                                        \
}
-
#define GP_REG_FIRST    0
#define GP_REG_LAST     31
#define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
@@ -763,6 +762,7 @@ extern int fast_interrupt;
extern int save_volatiles;

 #define INTERRUPT_HANDLER_NAME "_interrupt_handler"
+#define BREAK_HANDLER_NAME "_break_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 815d6b5..c368c70 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -1945,9 +1945,12 @@
(define_insn "*<optab>"
   [(any_return)]
   ""
-  { 
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14, 0\;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16, 8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14, 0\;%#"; 
     else
         return "rtsd\tr15, 8\;%#";
   }
@@ -1962,9 +1965,12 @@
   [(any_return)
    (use (match_operand:SI 0 "register_operand" ""))]
   ""
-  { 
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14,0 \;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16,8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14,0 \;%#"; 
     else
         return "rtsd\tr15,8 \;%#";
   }
@@ -2068,8 +2074,14 @@
     register rtx target2 = gen_rtx_REG (Pmode,
                     GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
     if (GET_CODE (target) == SYMBOL_REF) {
-        gen_rtx_CLOBBER (VOIDmode, target2);
-        return "brlid\tr15,%0\;%#";
+        if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brki\tr16,%0\;%#";
+        }
+        else { 
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brlid\tr15,%0\;%#";
+        }
     } else if (GET_CODE (target) == CONST_INT)
         return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
     else if (GET_CODE (target) == REG)
@@ -2173,13 +2185,15 @@
     if (GET_CODE (target) == SYMBOL_REF)
     {
       gen_rtx_CLOBBER (VOIDmode,target2);
-      if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
+      if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
+        return "brki\tr16,%1\;%#"; 
+      else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
         {
      return "brlid\tr15,%1\;%#";
         }
       else
         {
-      return "bralid\tr15,%1\;%#";
+        return "bralid\tr15,%1\;%#";
         }
     }
     else if (GET_CODE (target) == CONST_INT)
diff --git a/gcc/testsuite/gcc.target/microblaze/others/break_handler.c b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
new file mode 100644
index 0000000..1ccafd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
@@ -0,0 +1,15 @@
+int func () __attribute__ ((break_handler));
+volatile int intr_occurred;
+
+int func ()
+{
+
+  /* { dg-final { scan-assembler "rtbd\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),8" } } */
+    intr_occurred += 1;
+}
+int main()
+{
+    /* { dg-final { scan-assembler "brki\tr16" } } */
+    func();
+    return 0;
+}
-- 
1.7.1


-----Original Message-----
From: Michael Eager [mailto:eager@eagercon.com] 
Sent: Tuesday, May 06, 2014 8:04 PM
To: Ajit Kumar Agarwal; gcc-patches@gcc.gnu.org
Cc: Edgar Iglesias; John Williams; Vinod Kathail; Vidhumouli Hunsigida; Nagaraju Mekala
Subject: Re: [Patch,Microblaze]: Added Break Handler Support

On 05/06/14 06:10, Ajit Kumar Agarwal wrote:
> Hello All:
>
> Could you please review this patch.
>
> [PATCH] Break handler is used to support a normal hardware break.
> This is similar to interrupt_handler except that RTBD should be used instead of RTID.
>
> Changelog
>
> 2014-05-06 Nagaraju <nmekala@xilinx.com>
>
> * gcc/config/microblaze/microblaze-protos.h : Declaration of microblaze_is_break_handler.
> * gcc/config/microblaze/microblaze.c :  Add functions to support break 
> handler
> * gcc/config/microblaze/microblaze.h :  Add required defination declaration.
> * gcc/config/microblaze/microblaze.md : Add pattern for generating instruction rtbd.

Please follow conventions for ChangeLog.  For example
   * config/microblaze/microblaze.c (microblaze_break_function_p): New.

See http://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs

Add documentation for _break_handler.

Add test case(s).

Code formatting issues:
+  a = lookup_attribute("break_handler",DECL_ATTRIBUTES (func));
Space before left paren, after comma.
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+       	fputs ("_break_handler", file);
Incorrect indent.
+    if (microblaze_is_break_handler ())
+        return "rtbd\tr16, 0\;%#";
Ditto.
+    if (microblaze_is_break_handler ())
+        return "rtbd\tr16, 0\;%#";
Ditto.


> This email and any attachments are intended for the sole use of the 
> named recipient(s) and
> contain(s) confidential information that may be proprietary, 
> privileged or copyrighted under applicable law. If you are not the 
> intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

Mailing list conventions do not permit these kind of restrictive annotations.


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


[-- Attachment #2: 0001-Patch-microblaze-Added-Break-Handler-support.patch --]
[-- Type: application/octet-stream, Size: 11456 bytes --]

From 15dfaee8feef37430745d3dbc58f74bed876aabb Mon Sep 17 00:00:00 2001
From: Ajit Kumar Agarwal <ajitkum@xhdspdgnu.(none)>
Date: Tue, 13 May 2014 13:25:52 +0530
Subject: [PATCH] [Patch, microblaze] Added Break Handler support

Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
will be generating the rtbd instruction. At the call point where the software breaks are generated with
the instruction brki with register operand as r16.

2014-05-13 Ajit Agarwal <ajitkum@xilinx.com>

 * config/microblaze/microblaze.c
   (microblaze_break_function_p,microblaze_is_break_handler) : New

 * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro

 * config/microblaze/microblaze.md :
   Extended support for generation of brki instruction and rtbd instruction.

 * config/microblaze/microblaze-protos.h
   (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.

 * testsuite/gcc.target/microblaze/others/break_handler.c : New.

Signed-off-by:Nagaraju <nmekala@xilinx.com>
---
 gcc/config/microblaze/microblaze-protos.h          |    4 +-
 gcc/config/microblaze/microblaze.c                 |   47 +++++++++++++++++---
 gcc/config/microblaze/microblaze.h                 |    2 +-
 gcc/config/microblaze/microblaze.md                |   34 ++++++++++----
 .../gcc.target/microblaze/others/break_handler.c   |   15 ++++++
 5 files changed, 83 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/microblaze/others/break_handler.c

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index b03e9e1..f3cc099 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -40,10 +40,12 @@ 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_variant (void);
+extern int microblaze_is_break_handler (void);
+extern int microblaze_break_function_p (tree func);
 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);
-
+extern void microblaze_order_regs_for_local_alloc (void);
 extern int microblaze_regno_ok_for_base_p (int, int);
 extern HOST_WIDE_INT microblaze_initial_elimination_offset (int, int);
 extern void microblaze_declare_object (FILE *, const char *, const char *,
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index ba8109b..fc458a5 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -209,6 +209,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 break_handler;
 int fast_interrupt;
 int save_volatiles;
 
@@ -217,6 +218,8 @@ const struct attribute_spec microblaze_attribute_table[] = {
      affects_type_identity */
   {"interrupt_handler", 0,       0,     true,    false,   false,        NULL,
     false },
+  {"break_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,
@@ -1866,7 +1869,18 @@ microblaze_fast_interrupt_function_p (tree func)
   a = lookup_attribute ("fast_interrupt", DECL_ATTRIBUTES (func));
   return a != NULL_TREE;
 }
+int
+microblaze_break_function_p (tree func)
+{
+  tree a;
+  if (!func) 
+    return 0;
+  if (TREE_CODE (func) != FUNCTION_DECL)
+    return 0;
 
+  a = lookup_attribute ("break_handler", 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.  */
 
@@ -1891,6 +1905,13 @@ microblaze_is_interrupt_variant (void)
 {
   return (interrupt_handler || fast_interrupt);
 }
+int 
+microblaze_is_break_handler (void) 
+{ 
+  return break_handler; 
+} 
+
+ 
 
 /* Determine of register must be saved/restored in call.  */
 static int
@@ -1994,9 +2015,14 @@ compute_frame_size (HOST_WIDE_INT size)
 
   interrupt_handler =
     microblaze_interrupt_function_p (current_function_decl);
+  break_handler = 
+    microblaze_break_function_p (current_function_decl); 
+
   fast_interrupt =
     microblaze_fast_interrupt_function_p (current_function_decl);
   save_volatiles = microblaze_save_volatiles (current_function_decl);
+  if (break_handler)
+    interrupt_handler = break_handler;
 
   gp_reg_size = 0;
   mask = 0;
@@ -2641,9 +2667,11 @@ 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);
+        fputs ("_interrupt_handler", file);
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname)) 
+       	fputs ("_break_handler", file); 
       else if (fast_interrupt && strcmp (FAST_INTERRUPT_NAME, fnname))
-	fputs ("_fast_interrupt", file);
+        fputs ("_fast_interrupt", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2654,9 +2682,10 @@ microblaze_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
   assemble_name (file, fnname);
   fputs (":\n", file);
 
-  if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname))
+  if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname) && !break_handler)
     fputs ("_interrupt_handler:\n", file);
-
+  if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+    fputs ("_break_handler:\n", file);
   if (!flag_inhibit_size_directive)
     {
       /* .frame FRAMEREG, FRAMESIZE, RETREG.  */
@@ -2791,6 +2820,7 @@ microblaze_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = fsiz;
 
+
   /* If this function is a varargs function, store any registers that
      would normally hold arguments ($5 - $10) on the stack.  */
   if (((TYPE_ARG_TYPES (fntype) != 0
@@ -2892,8 +2922,10 @@ microblaze_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
   if (!flag_inhibit_size_directive)
     {
       fputs ("\t.end\t", file);
-      if (interrupt_handler)
+      if (interrupt_handler && !break_handler)
 	fputs ("_interrupt_handler", file);
+      else if (break_handler)
+        fputs ("_break_handler", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2934,7 +2966,7 @@ microblaze_expand_epilogue (void)
          sequence of load-followed by a use (in rtsd) in every prologue. Saves 
          a load-use stall cycle  :)   This is also important to handle alloca. 
          (See comments for if (frame_pointer_needed) below.  */
-
+      
       if (!crtl->is_leaf || interrupt_handler)
 	{
 	  mem_rtx =
@@ -3007,6 +3039,8 @@ microblaze_globalize_label (FILE * stream, const char *name)
     {
       if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME))
         fputs (INTERRUPT_HANDLER_NAME, stream);
+      else if (break_handler && strcmp (name, BREAK_HANDLER_NAME)) 
+        fputs (BREAK_HANDLER_NAME, stream); 
       else if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME))
         fputs (FAST_INTERRUPT_NAME, stream);
       fputs ("\n\t.globl\t", stream);
@@ -3247,7 +3281,6 @@ microblaze_expand_shift (rtx operands[])
 
   return 0;
 }
-
 /* Return an RTX indicating where the return address to the
    calling function can be found.  */
 rtx
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 58d8895..b979206 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -263,7 +263,6 @@ extern enum pipeline_type microblaze_pipe;
   1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
   1, 1, 1, 1								\
 }
-
 #define GP_REG_FIRST    0
 #define GP_REG_LAST     31
 #define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
@@ -763,6 +762,7 @@ extern int fast_interrupt;
 extern int save_volatiles;
 
 #define INTERRUPT_HANDLER_NAME "_interrupt_handler"
+#define BREAK_HANDLER_NAME "_break_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 815d6b5..c368c70 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -1945,9 +1945,12 @@
 (define_insn "*<optab>"
   [(any_return)]
   ""
-  { 
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14, 0\;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16, 8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14, 0\;%#"; 
     else
         return "rtsd\tr15, 8\;%#";
   }
@@ -1962,9 +1965,12 @@
   [(any_return)
    (use (match_operand:SI 0 "register_operand" ""))]
   ""
-  {	
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14,0 \;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16,8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14,0 \;%#"; 
     else
         return "rtsd\tr15,8 \;%#";
   }
@@ -2068,8 +2074,14 @@
     register rtx target2 = gen_rtx_REG (Pmode,
 			      GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
     if (GET_CODE (target) == SYMBOL_REF) {
-        gen_rtx_CLOBBER (VOIDmode, target2);
-        return "brlid\tr15,%0\;%#";
+        if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brki\tr16,%0\;%#";
+        }
+        else { 
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brlid\tr15,%0\;%#";
+        }
     } else if (GET_CODE (target) == CONST_INT)
         return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
     else if (GET_CODE (target) == REG)
@@ -2173,13 +2185,15 @@
     if (GET_CODE (target) == SYMBOL_REF)
     {
       gen_rtx_CLOBBER (VOIDmode,target2);
-      if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
+      if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
+        return "brki\tr16,%1\;%#"; 
+      else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
         {
 	  return "brlid\tr15,%1\;%#";
         }
       else
         {
-	  return "bralid\tr15,%1\;%#";
+	    return "bralid\tr15,%1\;%#";
         }
     }
     else if (GET_CODE (target) == CONST_INT)
diff --git a/gcc/testsuite/gcc.target/microblaze/others/break_handler.c b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
new file mode 100644
index 0000000..1ccafd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
@@ -0,0 +1,15 @@
+int func () __attribute__ ((break_handler));
+volatile int intr_occurred;
+
+int func ()
+{
+
+  /* { dg-final { scan-assembler "rtbd\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),8" } } */
+    intr_occurred += 1;
+}
+int main()
+{
+    /* { dg-final { scan-assembler "brki\tr16" } } */
+    func();
+    return 0;
+}
-- 
1.7.1


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

* Re: [Patch,Microblaze]: Added Break Handler Support
  2014-05-13  9:15   ` Ajit Kumar Agarwal
@ 2014-05-13 17:00     ` Michael Eager
  2014-05-13 19:15       ` Ajit Kumar Agarwal
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Eager @ 2014-05-13 17:00 UTC (permalink / raw)
  To: Ajit Kumar Agarwal, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

On 05/13/14 02:14, Ajit Kumar Agarwal wrote:
> Hello Michael:
>
> The following patch is to handle Software and Hardware breaks in Microblaze Architecture.
> Deja GNU testcase does not have any regressions and the testcase attached passes through.
> Review comments are incorporated.
>
> Okay for trunk?

Just saying OK would only be appropriate if you had write access to the repository.

> Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
> will be generating the rtbd instruction. At the call point where the software breaks are generated with
> the instruction brki with register operand as r16.
>
> 2014-05-13 Ajit Agarwal <ajitkum@xilinx.com>
>
> * config/microblaze/microblaze.c
>     (microblaze_break_function_p,microblaze_is_break_handler) : New
>
> * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro
>
> * config/microblaze/microblaze.md :
>    Extended support for generation of brki instruction and rtbd instruction.

A better ChangeLog entry is
* config/microblaze/microblaze.md (*<optab>,<optab>_internal):
     Add microblaze_is_break_handler () test.

Give specifics, naming functions, rather than making general comments.
As the ChangeLog standard says:
   It’s important to name the changed function or variable in full.
   Don’t abbreviate function or variable names, and don’t combine them.
   Subsequent maintainers will often search for a function name to find
   all the change log entries that pertain to it; if you abbreviate the
   name, they won’t find it when they search.

Mention each place where there are changes.  There should be a ChangeLog
entry for each non-trivial change.

Your patch made four significant changes to microblaze.md.
There appear to be several changes in microblaze.c, not just the definition
of the new functions as shown in your entry.


> * config/microblaze/microblaze-protos.h
>     (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.
>
> * testsuite/gcc.target/microblaze/others/break_handler.c : New.

Thanks for the test case.

As mentioned previously, add documentation for _break_handler.

> diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
> index b03e9e1..f3cc099 100644
> --- a/gcc/config/microblaze/microblaze-protos.h
> +++ b/gcc/config/microblaze/microblaze-protos.h

Please include the patch only once, not both inline and again as an
attachment.

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

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

* RE: [Patch,Microblaze]: Added Break Handler Support
  2014-05-13 17:00     ` Michael Eager
@ 2014-05-13 19:15       ` Ajit Kumar Agarwal
  2014-05-13 19:24         ` Michael Eager
  0 siblings, 1 reply; 9+ messages in thread
From: Ajit Kumar Agarwal @ 2014-05-13 19:15 UTC (permalink / raw)
  To: Michael Eager, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

Hello Michael:

Thanks for the comments on ChangeLog. Modified ChangeLog is inlined below.

2014-05-13 Ajit Agarwal <ajitkum@xilinx.com>
    
     * config/microblaze/microblaze.c
       (break_handler): New Declaration.
       (microblaze_break_function_p,microblaze_is_break_handler) : New function.
       (compute_frame_size): use of microblaze_break_function_p. Add the test of break_handler.
       (microblaze_function_prologue,microblaze_function_epilogue) : Add the test of variable
       break_handler.
       (microblaze_globalize_label) : Add the test of break_handler.
    
     * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro
    
     * config/microblaze/microblaze.md :
       (*<optab>,<optab>_internal): Add microblaze_is_break_handler () test.
       (call_internal1,call_value_intern) : Use of microblaze_break_function_p.
       Use of SYMBOL_REF_DECL.
    
     * config/microblaze/microblaze-protos.h
       (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.
    
     * testsuite/gcc.target/microblaze/others/break_handler.c : New.

Thanks & Regards
Ajit
-----Original Message-----
From: Michael Eager [mailto:eager@eagercon.com] 
Sent: Tuesday, May 13, 2014 10:30 PM
To: Ajit Kumar Agarwal; gcc-patches@gcc.gnu.org
Cc: Vinod Kathail; Vidhumouli Hunsigida; Nagaraju Mekala
Subject: Re: [Patch,Microblaze]: Added Break Handler Support

On 05/13/14 02:14, Ajit Kumar Agarwal wrote:
> Hello Michael:
>
> The following patch is to handle Software and Hardware breaks in Microblaze Architecture.
> Deja GNU testcase does not have any regressions and the testcase attached passes through.
> Review comments are incorporated.
>
> Okay for trunk?

Just saying OK would only be appropriate if you had write access to the repository.

> Added Break Handler support to incorporate the hardware and software 
> break. The Break Handler routine will be generating the rtbd 
> instruction. At the call point where the software breaks are generated with the instruction brki with register operand as r16.
>
> 2014-05-13 Ajit Agarwal <ajitkum@xilinx.com>
>
> * config/microblaze/microblaze.c
>     (microblaze_break_function_p,microblaze_is_break_handler) : New
>
> * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro
>
> * config/microblaze/microblaze.md :
>    Extended support for generation of brki instruction and rtbd instruction.

A better ChangeLog entry is
* config/microblaze/microblaze.md (*<optab>,<optab>_internal):
     Add microblaze_is_break_handler () test.

Give specifics, naming functions, rather than making general comments.
As the ChangeLog standard says:
   It’s important to name the changed function or variable in full.
   Don’t abbreviate function or variable names, and don’t combine them.
   Subsequent maintainers will often search for a function name to find
   all the change log entries that pertain to it; if you abbreviate the
   name, they won’t find it when they search.

Mention each place where there are changes.  There should be a ChangeLog entry for each non-trivial change.

Your patch made four significant changes to microblaze.md.
There appear to be several changes in microblaze.c, not just the definition of the new functions as shown in your entry.


> * config/microblaze/microblaze-protos.h
>     (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.
>
> * testsuite/gcc.target/microblaze/others/break_handler.c : New.

Thanks for the test case.

As mentioned previously, add documentation for _break_handler.

> diff --git a/gcc/config/microblaze/microblaze-protos.h 
> b/gcc/config/microblaze/microblaze-protos.h
> index b03e9e1..f3cc099 100644
> --- a/gcc/config/microblaze/microblaze-protos.h
> +++ b/gcc/config/microblaze/microblaze-protos.h

Please include the patch only once, not both inline and again as an attachment.

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


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

* Re: [Patch,Microblaze]: Added Break Handler Support
  2014-05-13 19:15       ` Ajit Kumar Agarwal
@ 2014-05-13 19:24         ` Michael Eager
  2014-05-13 21:42           ` Ajit Kumar Agarwal
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Eager @ 2014-05-13 19:24 UTC (permalink / raw)
  To: Ajit Kumar Agarwal, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

On 05/13/14 12:15, Ajit Kumar Agarwal wrote:
> Hello Michael:
>
> Thanks for the comments on ChangeLog. Modified ChangeLog is inlined below.

Please resubmit the patch with documentation for _break_handler.

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

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

* RE: [Patch,Microblaze]: Added Break Handler Support
  2014-05-13 19:24         ` Michael Eager
@ 2014-05-13 21:42           ` Ajit Kumar Agarwal
  2014-05-13 22:03             ` Michael Eager
  0 siblings, 1 reply; 9+ messages in thread
From: Ajit Kumar Agarwal @ 2014-05-13 21:42 UTC (permalink / raw)
  To: Michael Eager, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

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

Hello Michael:

Resubmitting the Patch with documentation for _break_handler in the config/microblaze/microblaze.h.

Thanks & Regards
Ajit

-----Original Message-----
From: Michael Eager [mailto:eager@eagercon.com] 
Sent: Wednesday, May 14, 2014 12:55 AM
To: Ajit Kumar Agarwal; gcc-patches@gcc.gnu.org
Cc: Vinod Kathail; Vidhumouli Hunsigida; Nagaraju Mekala
Subject: Re: [Patch,Microblaze]: Added Break Handler Support

On 05/13/14 12:15, Ajit Kumar Agarwal wrote:
> Hello Michael:
>
> Thanks for the comments on ChangeLog. Modified ChangeLog is inlined below.

Please resubmit the patch with documentation for _break_handler.

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

[-- Attachment #2: 0001-Patch-microblaze-Added-Break-Handler-support.patch --]
[-- Type: application/octet-stream, Size: 11939 bytes --]

From b4502f7b90f0cad4b784844a91fe1128673ef00e Mon Sep 17 00:00:00 2001
From: Ajit Kumar Agarwal <ajitkum@xhdspdgnu.(none)>
Date: Wed, 14 May 2014 02:34:15 +0530
Subject: [PATCH] [Patch, microblaze] Added Break Handler support

Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
will be generating the rtbd instruction. At the call point where the software breaks are generated with
the instruction brki with register operand as r16.

2014-05-14 Ajit Agarwal <ajitkum@xilinx.com

 * config/microblaze/microblaze.c
   (break_handler): New Declaration.
   (microblaze_break_function_p,microblaze_is_break_handler) : New function.
   (compute_frame_size): use of microblaze_break_function_p. Add the test of break_handler.
   (microblaze_function_prologue,microblaze_function_epilogue) : Add the test of variable
   break_handler.
   (microblaze_globalize_label) : Add the test of break_handler.

 * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro

 * config/microblaze/microblaze.md :
   (*<optab>,<optab>_internal): Add microblaze_is_break_handler () test.
   (call_internal1,call_value_intern) : Use of microblaze_break_function_p.
   Use of SYMBOL_REF_DECL.

 * config/microblaze/microblaze-protos.h
   (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.

 * testsuite/gcc.target/microblaze/others/break_handler.c : New.

Signed-off-by:Ajit Agarwal <ajitkum@xilinx.com>
---
 gcc/config/microblaze/microblaze-protos.h          |    4 +-
 gcc/config/microblaze/microblaze.c                 |   45 +++++++++++++++++---
 gcc/config/microblaze/microblaze.h                 |    5 ++-
 gcc/config/microblaze/microblaze.md                |   34 ++++++++++----
 .../gcc.target/microblaze/others/break_handler.c   |   15 +++++++
 5 files changed, 85 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/microblaze/others/break_handler.c

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index b03e9e1..f3cc099 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -40,10 +40,12 @@ 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_variant (void);
+extern int microblaze_is_break_handler (void);
+extern int microblaze_break_function_p (tree func);
 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);
-
+extern void microblaze_order_regs_for_local_alloc (void);
 extern int microblaze_regno_ok_for_base_p (int, int);
 extern HOST_WIDE_INT microblaze_initial_elimination_offset (int, int);
 extern void microblaze_declare_object (FILE *, const char *, const char *,
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index ba8109b..b7e9675 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -209,6 +209,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 break_handler;
 int fast_interrupt;
 int save_volatiles;
 
@@ -217,6 +218,8 @@ const struct attribute_spec microblaze_attribute_table[] = {
      affects_type_identity */
   {"interrupt_handler", 0,       0,     true,    false,   false,        NULL,
     false },
+  {"break_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,
@@ -1866,7 +1869,18 @@ microblaze_fast_interrupt_function_p (tree func)
   a = lookup_attribute ("fast_interrupt", DECL_ATTRIBUTES (func));
   return a != NULL_TREE;
 }
+int
+microblaze_break_function_p (tree func)
+{
+  tree a;
+  if (!func) 
+    return 0;
+  if (TREE_CODE (func) != FUNCTION_DECL)
+    return 0;
 
+  a = lookup_attribute ("break_handler", 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.  */
 
@@ -1891,6 +1905,13 @@ microblaze_is_interrupt_variant (void)
 {
   return (interrupt_handler || fast_interrupt);
 }
+int 
+microblaze_is_break_handler (void) 
+{ 
+  return break_handler; 
+} 
+
+ 
 
 /* Determine of register must be saved/restored in call.  */
 static int
@@ -1994,9 +2015,14 @@ compute_frame_size (HOST_WIDE_INT size)
 
   interrupt_handler =
     microblaze_interrupt_function_p (current_function_decl);
+  break_handler = 
+    microblaze_break_function_p (current_function_decl); 
+
   fast_interrupt =
     microblaze_fast_interrupt_function_p (current_function_decl);
   save_volatiles = microblaze_save_volatiles (current_function_decl);
+  if (break_handler)
+    interrupt_handler = break_handler;
 
   gp_reg_size = 0;
   mask = 0;
@@ -2641,9 +2667,11 @@ 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);
+        fputs ("_interrupt_handler", file);
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname)) 
+       	fputs ("_break_handler", file); 
       else if (fast_interrupt && strcmp (FAST_INTERRUPT_NAME, fnname))
-	fputs ("_fast_interrupt", file);
+        fputs ("_fast_interrupt", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2656,7 +2684,8 @@ microblaze_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
   if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname))
     fputs ("_interrupt_handler:\n", file);
-
+  if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+    fputs ("_break_handler:\n", file);
   if (!flag_inhibit_size_directive)
     {
       /* .frame FRAMEREG, FRAMESIZE, RETREG.  */
@@ -2791,6 +2820,7 @@ microblaze_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = fsiz;
 
+
   /* If this function is a varargs function, store any registers that
      would normally hold arguments ($5 - $10) on the stack.  */
   if (((TYPE_ARG_TYPES (fntype) != 0
@@ -2892,8 +2922,10 @@ microblaze_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
   if (!flag_inhibit_size_directive)
     {
       fputs ("\t.end\t", file);
-      if (interrupt_handler)
+      if (interrupt_handler && !break_handler)
 	fputs ("_interrupt_handler", file);
+      else if (break_handler)
+        fputs ("_break_handler", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2934,7 +2966,7 @@ microblaze_expand_epilogue (void)
          sequence of load-followed by a use (in rtsd) in every prologue. Saves 
          a load-use stall cycle  :)   This is also important to handle alloca. 
          (See comments for if (frame_pointer_needed) below.  */
-
+      
       if (!crtl->is_leaf || interrupt_handler)
 	{
 	  mem_rtx =
@@ -3007,6 +3039,8 @@ microblaze_globalize_label (FILE * stream, const char *name)
     {
       if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME))
         fputs (INTERRUPT_HANDLER_NAME, stream);
+      else if (break_handler && strcmp (name, BREAK_HANDLER_NAME)) 
+        fputs (BREAK_HANDLER_NAME, stream); 
       else if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME))
         fputs (FAST_INTERRUPT_NAME, stream);
       fputs ("\n\t.globl\t", stream);
@@ -3247,7 +3281,6 @@ microblaze_expand_shift (rtx operands[])
 
   return 0;
 }
-
 /* Return an RTX indicating where the return address to the
    calling function can be found.  */
 rtx
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 58d8895..edb7d8a 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -263,7 +263,6 @@ extern enum pipeline_type microblaze_pipe;
   1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
   1, 1, 1, 1								\
 }
-
 #define GP_REG_FIRST    0
 #define GP_REG_LAST     31
 #define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
@@ -763,6 +762,10 @@ extern int fast_interrupt;
 extern int save_volatiles;
 
 #define INTERRUPT_HANDLER_NAME "_interrupt_handler"
+/* The function name for the function tagged with attribute break_handler
+   has been set in the RTL as _break_handler. This function name is used
+   in the generation of directives .ent .end and .global. */
+#define BREAK_HANDLER_NAME "_break_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 815d6b5..c368c70 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -1945,9 +1945,12 @@
 (define_insn "*<optab>"
   [(any_return)]
   ""
-  { 
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14, 0\;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16, 8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14, 0\;%#"; 
     else
         return "rtsd\tr15, 8\;%#";
   }
@@ -1962,9 +1965,12 @@
   [(any_return)
    (use (match_operand:SI 0 "register_operand" ""))]
   ""
-  {	
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14,0 \;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16,8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14,0 \;%#"; 
     else
         return "rtsd\tr15,8 \;%#";
   }
@@ -2068,8 +2074,14 @@
     register rtx target2 = gen_rtx_REG (Pmode,
 			      GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
     if (GET_CODE (target) == SYMBOL_REF) {
-        gen_rtx_CLOBBER (VOIDmode, target2);
-        return "brlid\tr15,%0\;%#";
+        if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brki\tr16,%0\;%#";
+        }
+        else { 
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brlid\tr15,%0\;%#";
+        }
     } else if (GET_CODE (target) == CONST_INT)
         return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
     else if (GET_CODE (target) == REG)
@@ -2173,13 +2185,15 @@
     if (GET_CODE (target) == SYMBOL_REF)
     {
       gen_rtx_CLOBBER (VOIDmode,target2);
-      if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
+      if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
+        return "brki\tr16,%1\;%#"; 
+      else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
         {
 	  return "brlid\tr15,%1\;%#";
         }
       else
         {
-	  return "bralid\tr15,%1\;%#";
+	    return "bralid\tr15,%1\;%#";
         }
     }
     else if (GET_CODE (target) == CONST_INT)
diff --git a/gcc/testsuite/gcc.target/microblaze/others/break_handler.c b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
new file mode 100644
index 0000000..1ccafd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
@@ -0,0 +1,15 @@
+int func () __attribute__ ((break_handler));
+volatile int intr_occurred;
+
+int func ()
+{
+
+  /* { dg-final { scan-assembler "rtbd\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),8" } } */
+    intr_occurred += 1;
+}
+int main()
+{
+    /* { dg-final { scan-assembler "brki\tr16" } } */
+    func();
+    return 0;
+}
-- 
1.7.1


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

* Re: [Patch,Microblaze]: Added Break Handler Support
  2014-05-13 21:42           ` Ajit Kumar Agarwal
@ 2014-05-13 22:03             ` Michael Eager
  2014-05-14  9:27               ` Ajit Kumar Agarwal
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Eager @ 2014-05-13 22:03 UTC (permalink / raw)
  To: Ajit Kumar Agarwal, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

On 05/13/14 14:42, Ajit Kumar Agarwal wrote:
> Hello Michael:
>
> Resubmitting the Patch with documentation for _break_handler in the config/microblaze/microblaze.h.

Please put everything together in one place.
When you resubmit a patch, include the ChangeLog.

I'm not sure what you changed, but there are no changes to
gcc/doc/extend.texi in your patch.


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

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

* RE: [Patch,Microblaze]: Added Break Handler Support
  2014-05-13 22:03             ` Michael Eager
@ 2014-05-14  9:27               ` Ajit Kumar Agarwal
  2014-05-17 15:14                 ` Michael Eager
  0 siblings, 1 reply; 9+ messages in thread
From: Ajit Kumar Agarwal @ 2014-05-14  9:27 UTC (permalink / raw)
  To: Michael Eager, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

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

Based on the Feedback, Resubmitting the Updated Patch.

[Patch, MicroBlaze] Add break Handler Support

Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
will be generating the rtbd instruction. At the call point where the software breaks are generated with
the instruction brki with register operand as r16.

ChangeLog:

2014-05-14 Ajit Agarwal <ajitkum@xilinx.com>

 * config/microblaze/microblaze.c
   (break_handler): New Declaration.
   (microblaze_break_function_p,microblaze_is_break_handler) : New functions.
   (compute_frame_size): use of microblaze_break_function_p. Add the test of break_handler.
   (microblaze_function_prologue) : Add the test of variable
   break_handler. Check the fnname by BREAK_HANDLER_NAME.
   (microblaze_function_epilogue) : Add the test of break_handler.
   (microblaze_globalize_label) : Add the test of break_handler. Check the
   name by BREAK_HANDLER_NAME.

 * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro

 * config/microblaze/microblaze.md :
   (*<optab>,<optab>_internal): Add microblaze_is_break_handler () test.
   (call_internal1,call_value_intern) : Use of microblaze_break_function_p.
   Use of SYMBOL_REF_DECL.

 * config/microblaze/microblaze-protos.h
   (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.

 * testsuite/gcc.target/microblaze/others/break_handler.c : New.

 * doc/extend.texi( MicroBlaze break_handler Functions): Document new
   MicroBlaze break_handler functions.

Signed-off-by:Ajit Agarwal <ajitkum@xilinx.com>
---
 gcc/config/microblaze/microblaze-protos.h          |    4 +-
 gcc/config/microblaze/microblaze.c                 |   45 +++++++++++++++++---
 gcc/config/microblaze/microblaze.h                 |    5 ++-
 gcc/config/microblaze/microblaze.md                |   34 ++++++++++----
 gcc/doc/extend.texi                                |   12 +++++
 .../gcc.target/microblaze/others/break_handler.c   |   15 +++++++
 6 files changed, 97 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/microblaze/others/break_handler.c

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index b03e9e1..f3cc099 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -40,10 +40,12 @@ 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_variant (void);
+extern int microblaze_is_break_handler (void);
+extern int microblaze_break_function_p (tree func);
 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);
-
+extern void microblaze_order_regs_for_local_alloc (void);
 extern int microblaze_regno_ok_for_base_p (int, int);
 extern HOST_WIDE_INT microblaze_initial_elimination_offset (int, int);
 extern void microblaze_declare_object (FILE *, const char *, const char *,
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index ba8109b..b7e9675 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -209,6 +209,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 break_handler;
 int fast_interrupt;
 int save_volatiles;
 
@@ -217,6 +218,8 @@ const struct attribute_spec microblaze_attribute_table[] = {
      affects_type_identity */
   {"interrupt_handler", 0,       0,     true,    false,   false,        NULL,
     false },
+  {"break_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,
@@ -1866,7 +1869,18 @@ microblaze_fast_interrupt_function_p (tree func)
   a = lookup_attribute ("fast_interrupt", DECL_ATTRIBUTES (func));
   return a != NULL_TREE;
 }
+int
+microblaze_break_function_p (tree func)
+{
+  tree a;
+  if (!func) 
+    return 0;
+  if (TREE_CODE (func) != FUNCTION_DECL)
+    return 0;
 
+  a = lookup_attribute ("break_handler", 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.  */
 
@@ -1891,6 +1905,13 @@ microblaze_is_interrupt_variant (void)
 {
   return (interrupt_handler || fast_interrupt);
 }
+int 
+microblaze_is_break_handler (void) 
+{ 
+  return break_handler; 
+} 
+
+ 
 
 /* Determine of register must be saved/restored in call.  */
 static int
@@ -1994,9 +2015,14 @@ compute_frame_size (HOST_WIDE_INT size)
 
   interrupt_handler =
     microblaze_interrupt_function_p (current_function_decl);
+  break_handler = 
+    microblaze_break_function_p (current_function_decl); 
+
   fast_interrupt =
     microblaze_fast_interrupt_function_p (current_function_decl);
   save_volatiles = microblaze_save_volatiles (current_function_decl);
+  if (break_handler)
+    interrupt_handler = break_handler;
 
   gp_reg_size = 0;
   mask = 0;
@@ -2641,9 +2667,11 @@ 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);
+        fputs ("_interrupt_handler", file);
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname)) 
+       	fputs ("_break_handler", file); 
       else if (fast_interrupt && strcmp (FAST_INTERRUPT_NAME, fnname))
-	fputs ("_fast_interrupt", file);
+        fputs ("_fast_interrupt", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2656,7 +2684,8 @@ microblaze_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
   if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname))
     fputs ("_interrupt_handler:\n", file);
-
+  if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+    fputs ("_break_handler:\n", file);
   if (!flag_inhibit_size_directive)
     {
       /* .frame FRAMEREG, FRAMESIZE, RETREG.  */
@@ -2791,6 +2820,7 @@ microblaze_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = fsiz;
 
+
   /* If this function is a varargs function, store any registers that
      would normally hold arguments ($5 - $10) on the stack.  */
   if (((TYPE_ARG_TYPES (fntype) != 0
@@ -2892,8 +2922,10 @@ microblaze_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
   if (!flag_inhibit_size_directive)
     {
       fputs ("\t.end\t", file);
-      if (interrupt_handler)
+      if (interrupt_handler && !break_handler)
 	fputs ("_interrupt_handler", file);
+      else if (break_handler)
+        fputs ("_break_handler", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2934,7 +2966,7 @@ microblaze_expand_epilogue (void)
          sequence of load-followed by a use (in rtsd) in every prologue. Saves 
          a load-use stall cycle  :)   This is also important to handle alloca. 
          (See comments for if (frame_pointer_needed) below.  */
-
+      
       if (!crtl->is_leaf || interrupt_handler)
 	{
 	  mem_rtx =
@@ -3007,6 +3039,8 @@ microblaze_globalize_label (FILE * stream, const char *name)
     {
       if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME))
         fputs (INTERRUPT_HANDLER_NAME, stream);
+      else if (break_handler && strcmp (name, BREAK_HANDLER_NAME)) 
+        fputs (BREAK_HANDLER_NAME, stream); 
       else if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME))
         fputs (FAST_INTERRUPT_NAME, stream);
       fputs ("\n\t.globl\t", stream);
@@ -3247,7 +3281,6 @@ microblaze_expand_shift (rtx operands[])
 
   return 0;
 }
-
 /* Return an RTX indicating where the return address to the
    calling function can be found.  */
 rtx
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 58d8895..edb7d8a 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -263,7 +263,6 @@ extern enum pipeline_type microblaze_pipe;
   1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
   1, 1, 1, 1								\
 }
-
 #define GP_REG_FIRST    0
 #define GP_REG_LAST     31
 #define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
@@ -763,6 +762,10 @@ extern int fast_interrupt;
 extern int save_volatiles;
 
 #define INTERRUPT_HANDLER_NAME "_interrupt_handler"
+/* The function name for the function tagged with attribute break_handler
+   has been set in the RTL as _break_handler. This function name is used
+   in the generation of directives .ent .end and .global. */
+#define BREAK_HANDLER_NAME "_break_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 815d6b5..c368c70 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -1945,9 +1945,12 @@
 (define_insn "*<optab>"
   [(any_return)]
   ""
-  { 
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14, 0\;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16, 8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14, 0\;%#"; 
     else
         return "rtsd\tr15, 8\;%#";
   }
@@ -1962,9 +1965,12 @@
   [(any_return)
    (use (match_operand:SI 0 "register_operand" ""))]
   ""
-  {	
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14,0 \;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16,8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14,0 \;%#"; 
     else
         return "rtsd\tr15,8 \;%#";
   }
@@ -2068,8 +2074,14 @@
     register rtx target2 = gen_rtx_REG (Pmode,
 			      GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
     if (GET_CODE (target) == SYMBOL_REF) {
-        gen_rtx_CLOBBER (VOIDmode, target2);
-        return "brlid\tr15,%0\;%#";
+        if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brki\tr16,%0\;%#";
+        }
+        else { 
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brlid\tr15,%0\;%#";
+        }
     } else if (GET_CODE (target) == CONST_INT)
         return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
     else if (GET_CODE (target) == REG)
@@ -2173,13 +2185,15 @@
     if (GET_CODE (target) == SYMBOL_REF)
     {
       gen_rtx_CLOBBER (VOIDmode,target2);
-      if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
+      if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
+        return "brki\tr16,%1\;%#"; 
+      else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
         {
 	  return "brlid\tr15,%1\;%#";
         }
       else
         {
-	  return "bralid\tr15,%1\;%#";
+	    return "bralid\tr15,%1\;%#";
         }
     }
     else if (GET_CODE (target) == CONST_INT)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 9780d92..adb6410 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3776,6 +3776,18 @@ registers) are saved in the function prologue.  If the function is a leaf
 function, only volatiles used by the function are saved.  A normal function
 return is generated instead of a return from interrupt.
 
+@item break_handler 
+@cindex break handler functions
+Use this attribute on the MicroBlaze ports to indicate that
+the specified function is an break handler.  The compiler generates function 
+entry and exit sequences suitable for use in an break handler when this 
+attribute is present. The return from @code{break_handler} is done through
+the @code{rtbd} instead of @code{rtsd}.
+
+@smallexample
+void f () __attribute__ ((break_handler));
+@end smallexample
+
 @item section ("@var{section-name}")
 @cindex @code{section} function attribute
 Normally, the compiler places the code it generates in the @code{text} section.
diff --git a/gcc/testsuite/gcc.target/microblaze/others/break_handler.c b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
new file mode 100644
index 0000000..1ccafd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
@@ -0,0 +1,15 @@
+int func () __attribute__ ((break_handler));
+volatile int intr_occurred;
+
+int func ()
+{
+
+  /* { dg-final { scan-assembler "rtbd\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),8" } } */
+    intr_occurred += 1;
+}
+int main()
+{
+    /* { dg-final { scan-assembler "brki\tr16" } } */
+    func();
+    return 0;
+}
-- 
1.7.1

-----Original Message-----
From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-owner@gcc.gnu.org] On Behalf Of Michael Eager
Sent: Wednesday, May 14, 2014 3:33 AM
To: Ajit Kumar Agarwal; gcc-patches@gcc.gnu.org
Cc: Vinod Kathail; Vidhumouli Hunsigida; Nagaraju Mekala
Subject: Re: [Patch,Microblaze]: Added Break Handler Support

On 05/13/14 14:42, Ajit Kumar Agarwal wrote:
> Hello Michael:
>
> Resubmitting the Patch with documentation for _break_handler in the config/microblaze/microblaze.h.

Please put everything together in one place.
When you resubmit a patch, include the ChangeLog.

I'm not sure what you changed, but there are no changes to gcc/doc/extend.texi in your patch.


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

[-- Attachment #2: 0001-Patch-MicroBlaze-Add-break-Handler-Support.patch --]
[-- Type: application/octet-stream, Size: 13245 bytes --]

From 3b454de6a8505c648e4424e690f2f988b168d968 Mon Sep 17 00:00:00 2001
From: Ajit Kumar Agarwal <ajitkum@xhdspdgnu.(none)>
Date: Wed, 14 May 2014 14:26:34 +0530
Subject: [PATCH] [Patch, MicroBlaze] Add break Handler Support

Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
will be generating the rtbd instruction. At the call point where the software breaks are generated with
the instruction brki with register operand as r16.

ChangeLog:

2014-05-14 Ajit Agarwal <ajitkum@xilinx.com>

 * config/microblaze/microblaze.c
   (break_handler): New Declaration.
   (microblaze_break_function_p,microblaze_is_break_handler) : New functions.
   (compute_frame_size): use of microblaze_break_function_p. Add the test of break_handler.
   (microblaze_function_prologue) : Add the test of variable
   break_handler. Check the fnname by BREAK_HANDLER_NAME.
   (microblaze_function_epilogue) : Add the test of break_handler.
   (microblaze_globalize_label) : Add the test of break_handler. Check the
   name by BREAK_HANDLER_NAME.

 * config/microblaze/microblaze.h (BREAK_HANDLER_NAME) : New macro

 * config/microblaze/microblaze.md :
   (*<optab>,<optab>_internal): Add microblaze_is_break_handler () test.
   (call_internal1,call_value_intern) : Use of microblaze_break_function_p.
   Use of SYMBOL_REF_DECL.

 * config/microblaze/microblaze-protos.h
   (microblaze_break_function_p,microblaze_is_break_handler) : New Declaration.

 * testsuite/gcc.target/microblaze/others/break_handler.c : New.

 * doc/extend.texi( MicroBlaze break_handler Functions): Document new
   MicroBlaze break_handler functions.

Signed-off-by:Ajit Agarwal <ajitkum@xilinx.com>
---
 gcc/config/microblaze/microblaze-protos.h          |    4 +-
 gcc/config/microblaze/microblaze.c                 |   45 +++++++++++++++++---
 gcc/config/microblaze/microblaze.h                 |    5 ++-
 gcc/config/microblaze/microblaze.md                |   34 ++++++++++----
 gcc/doc/extend.texi                                |   12 +++++
 .../gcc.target/microblaze/others/break_handler.c   |   15 +++++++
 6 files changed, 97 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/microblaze/others/break_handler.c

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index b03e9e1..f3cc099 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -40,10 +40,12 @@ 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_variant (void);
+extern int microblaze_is_break_handler (void);
+extern int microblaze_break_function_p (tree func);
 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);
-
+extern void microblaze_order_regs_for_local_alloc (void);
 extern int microblaze_regno_ok_for_base_p (int, int);
 extern HOST_WIDE_INT microblaze_initial_elimination_offset (int, int);
 extern void microblaze_declare_object (FILE *, const char *, const char *,
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index ba8109b..b7e9675 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -209,6 +209,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 break_handler;
 int fast_interrupt;
 int save_volatiles;
 
@@ -217,6 +218,8 @@ const struct attribute_spec microblaze_attribute_table[] = {
      affects_type_identity */
   {"interrupt_handler", 0,       0,     true,    false,   false,        NULL,
     false },
+  {"break_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,
@@ -1866,7 +1869,18 @@ microblaze_fast_interrupt_function_p (tree func)
   a = lookup_attribute ("fast_interrupt", DECL_ATTRIBUTES (func));
   return a != NULL_TREE;
 }
+int
+microblaze_break_function_p (tree func)
+{
+  tree a;
+  if (!func) 
+    return 0;
+  if (TREE_CODE (func) != FUNCTION_DECL)
+    return 0;
 
+  a = lookup_attribute ("break_handler", 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.  */
 
@@ -1891,6 +1905,13 @@ microblaze_is_interrupt_variant (void)
 {
   return (interrupt_handler || fast_interrupt);
 }
+int 
+microblaze_is_break_handler (void) 
+{ 
+  return break_handler; 
+} 
+
+ 
 
 /* Determine of register must be saved/restored in call.  */
 static int
@@ -1994,9 +2015,14 @@ compute_frame_size (HOST_WIDE_INT size)
 
   interrupt_handler =
     microblaze_interrupt_function_p (current_function_decl);
+  break_handler = 
+    microblaze_break_function_p (current_function_decl); 
+
   fast_interrupt =
     microblaze_fast_interrupt_function_p (current_function_decl);
   save_volatiles = microblaze_save_volatiles (current_function_decl);
+  if (break_handler)
+    interrupt_handler = break_handler;
 
   gp_reg_size = 0;
   mask = 0;
@@ -2641,9 +2667,11 @@ 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);
+        fputs ("_interrupt_handler", file);
+      else if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname)) 
+       	fputs ("_break_handler", file); 
       else if (fast_interrupt && strcmp (FAST_INTERRUPT_NAME, fnname))
-	fputs ("_fast_interrupt", file);
+        fputs ("_fast_interrupt", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2656,7 +2684,8 @@ microblaze_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
   if (interrupt_handler && strcmp (INTERRUPT_HANDLER_NAME, fnname))
     fputs ("_interrupt_handler:\n", file);
-
+  if (break_handler && strcmp (BREAK_HANDLER_NAME, fnname))
+    fputs ("_break_handler:\n", file);
   if (!flag_inhibit_size_directive)
     {
       /* .frame FRAMEREG, FRAMESIZE, RETREG.  */
@@ -2791,6 +2820,7 @@ microblaze_expand_prologue (void)
   if (flag_stack_usage_info)
     current_function_static_stack_size = fsiz;
 
+
   /* If this function is a varargs function, store any registers that
      would normally hold arguments ($5 - $10) on the stack.  */
   if (((TYPE_ARG_TYPES (fntype) != 0
@@ -2892,8 +2922,10 @@ microblaze_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
   if (!flag_inhibit_size_directive)
     {
       fputs ("\t.end\t", file);
-      if (interrupt_handler)
+      if (interrupt_handler && !break_handler)
 	fputs ("_interrupt_handler", file);
+      else if (break_handler)
+        fputs ("_break_handler", file);
       else
 	assemble_name (file, fnname);
       fputs ("\n", file);
@@ -2934,7 +2966,7 @@ microblaze_expand_epilogue (void)
          sequence of load-followed by a use (in rtsd) in every prologue. Saves 
          a load-use stall cycle  :)   This is also important to handle alloca. 
          (See comments for if (frame_pointer_needed) below.  */
-
+      
       if (!crtl->is_leaf || interrupt_handler)
 	{
 	  mem_rtx =
@@ -3007,6 +3039,8 @@ microblaze_globalize_label (FILE * stream, const char *name)
     {
       if (interrupt_handler && strcmp (name, INTERRUPT_HANDLER_NAME))
         fputs (INTERRUPT_HANDLER_NAME, stream);
+      else if (break_handler && strcmp (name, BREAK_HANDLER_NAME)) 
+        fputs (BREAK_HANDLER_NAME, stream); 
       else if (fast_interrupt && strcmp (name, FAST_INTERRUPT_NAME))
         fputs (FAST_INTERRUPT_NAME, stream);
       fputs ("\n\t.globl\t", stream);
@@ -3247,7 +3281,6 @@ microblaze_expand_shift (rtx operands[])
 
   return 0;
 }
-
 /* Return an RTX indicating where the return address to the
    calling function can be found.  */
 rtx
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 58d8895..edb7d8a 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -263,7 +263,6 @@ extern enum pipeline_type microblaze_pipe;
   1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			\
   1, 1, 1, 1								\
 }
-
 #define GP_REG_FIRST    0
 #define GP_REG_LAST     31
 #define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
@@ -763,6 +762,10 @@ extern int fast_interrupt;
 extern int save_volatiles;
 
 #define INTERRUPT_HANDLER_NAME "_interrupt_handler"
+/* The function name for the function tagged with attribute break_handler
+   has been set in the RTL as _break_handler. This function name is used
+   in the generation of directives .ent .end and .global. */
+#define BREAK_HANDLER_NAME "_break_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 815d6b5..c368c70 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -1945,9 +1945,12 @@
 (define_insn "*<optab>"
   [(any_return)]
   ""
-  { 
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14, 0\;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16, 8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14, 0\;%#"; 
     else
         return "rtsd\tr15, 8\;%#";
   }
@@ -1962,9 +1965,12 @@
   [(any_return)
    (use (match_operand:SI 0 "register_operand" ""))]
   ""
-  {	
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14,0 \;%#";
+  {
+    if (microblaze_is_break_handler ()) 
+        return "rtbd\tr16,8\;%#"; 
+    else if (microblaze_is_interrupt_variant () 
+             && (!microblaze_is_break_handler())) 
+        return "rtid\tr14,0 \;%#"; 
     else
         return "rtsd\tr15,8 \;%#";
   }
@@ -2068,8 +2074,14 @@
     register rtx target2 = gen_rtx_REG (Pmode,
 			      GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
     if (GET_CODE (target) == SYMBOL_REF) {
-        gen_rtx_CLOBBER (VOIDmode, target2);
-        return "brlid\tr15,%0\;%#";
+        if (microblaze_break_function_p (SYMBOL_REF_DECL (target))) {
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brki\tr16,%0\;%#";
+        }
+        else { 
+            gen_rtx_CLOBBER (VOIDmode, target2);
+            return "brlid\tr15,%0\;%#";
+        }
     } else if (GET_CODE (target) == CONST_INT)
         return "la\t%@,r0,%0\;brald\tr15,%@\;%#";
     else if (GET_CODE (target) == REG)
@@ -2173,13 +2185,15 @@
     if (GET_CODE (target) == SYMBOL_REF)
     {
       gen_rtx_CLOBBER (VOIDmode,target2);
-      if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
+      if (microblaze_break_function_p (SYMBOL_REF_DECL (target)))
+        return "brki\tr16,%1\;%#"; 
+      else if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
         {
 	  return "brlid\tr15,%1\;%#";
         }
       else
         {
-	  return "bralid\tr15,%1\;%#";
+	    return "bralid\tr15,%1\;%#";
         }
     }
     else if (GET_CODE (target) == CONST_INT)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 9780d92..adb6410 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3776,6 +3776,18 @@ registers) are saved in the function prologue.  If the function is a leaf
 function, only volatiles used by the function are saved.  A normal function
 return is generated instead of a return from interrupt.
 
+@item break_handler 
+@cindex break handler functions
+Use this attribute on the MicroBlaze ports to indicate that
+the specified function is an break handler.  The compiler generates function 
+entry and exit sequences suitable for use in an break handler when this 
+attribute is present. The return from @code{break_handler} is done through
+the @code{rtbd} instead of @code{rtsd}.
+
+@smallexample
+void f () __attribute__ ((break_handler));
+@end smallexample
+
 @item section ("@var{section-name}")
 @cindex @code{section} function attribute
 Normally, the compiler places the code it generates in the @code{text} section.
diff --git a/gcc/testsuite/gcc.target/microblaze/others/break_handler.c b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
new file mode 100644
index 0000000..1ccafd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/microblaze/others/break_handler.c
@@ -0,0 +1,15 @@
+int func () __attribute__ ((break_handler));
+volatile int intr_occurred;
+
+int func ()
+{
+
+  /* { dg-final { scan-assembler "rtbd\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),8" } } */
+    intr_occurred += 1;
+}
+int main()
+{
+    /* { dg-final { scan-assembler "brki\tr16" } } */
+    func();
+    return 0;
+}
-- 
1.7.1


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

* Re: [Patch,Microblaze]: Added Break Handler Support
  2014-05-14  9:27               ` Ajit Kumar Agarwal
@ 2014-05-17 15:14                 ` Michael Eager
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Eager @ 2014-05-17 15:14 UTC (permalink / raw)
  To: Ajit Kumar Agarwal, gcc-patches
  Cc: Vinod Kathail, Vidhumouli Hunsigida, Nagaraju Mekala

On 05/14/14 02:24, Ajit Kumar Agarwal wrote:
> Based on the Feedback, Resubmitting the Updated Patch.
>
> [Patch, MicroBlaze] Add break Handler Support
>
> Added Break Handler support to incorporate the hardware and software break. The Break Handler routine
> will be generating the rtbd instruction. At the call point where the software breaks are generated with
> the instruction brki with register operand as r16.

I made the following changes:

Your patch:
> diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
> index 815d6b5..c368c70 100644
> --- a/gcc/config/microblaze/microblaze.md
> +++ b/gcc/config/microblaze/microblaze.md
> @@ -1945,9 +1945,12 @@
>   (define_insn "*<optab>"
>     [(any_return)]
>     ""
> -  {
> -    if (microblaze_is_interrupt_variant ())
> -        return "rtid\tr14, 0\;%#";
> +  {
> +    if (microblaze_is_break_handler ())
> +        return "rtbd\tr16, 8\;%#";
> +    else if (microblaze_is_interrupt_variant ()
> +             && (!microblaze_is_break_handler()))

Replaced with:
-  {
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14, 0\;%#";
+  {
+    if (microblaze_is_break_handler ())
+        return "rtbd\tr16, 8\;%#";
+    else if (microblaze_is_interrupt_variant ())
+        return "rtid\tr14, 0\;%#";

Your patch:
> @@ -1962,9 +1965,12 @@
>     [(any_return)
>      (use (match_operand:SI 0 "register_operand" ""))]
>     ""
> -  {	
> -    if (microblaze_is_interrupt_variant ())
> -        return "rtid\tr14,0 \;%#";
> +  {
> +    if (microblaze_is_break_handler ())
> +        return "rtbd\tr16,8\;%#";
> +    else if (microblaze_is_interrupt_variant ()
> +             && (!microblaze_is_break_handler()))
> +        return "rtid\tr14,0 \;%#";

Replaced with
-  {	
-    if (microblaze_is_interrupt_variant ())
-        return "rtid\tr14,0 \;%#";
+  {
+    if (microblaze_is_break_handler ())
+        return "rtbd\tr16,8\;%#";
+    else if (microblaze_is_interrupt_variant ())
+        return "rtid\tr14,0 \;%#";

Please remove trailing white space in future patches.

The code in the "call_internal" pattern does not follow GNU indent
conventions.  If you are modifying code which does not follow these
conventions, please bring it up to date, rather than repeating the
indent violations.

Committed revision 210559.

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

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

end of thread, other threads:[~2014-05-17 15:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <345d2b49-c710-4795-924b-217a5221921c@CO9EHSMHS012.ehs.local>
2014-05-06 15:00 ` [Patch,Microblaze]: Added Break Handler Support Michael Eager
     [not found] ` <5368F2DA.9090509@eagercon.com>
2014-05-13  9:15   ` Ajit Kumar Agarwal
2014-05-13 17:00     ` Michael Eager
2014-05-13 19:15       ` Ajit Kumar Agarwal
2014-05-13 19:24         ` Michael Eager
2014-05-13 21:42           ` Ajit Kumar Agarwal
2014-05-13 22:03             ` Michael Eager
2014-05-14  9:27               ` Ajit Kumar Agarwal
2014-05-17 15:14                 ` 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).