]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add fast interrupt.
authorDavid Holsgrove <david.holsgrove@xilinx.com>
Tue, 5 Mar 2013 19:34:25 +0000 (19:34 +0000)
committerMichael Eager <eager@gcc.gnu.org>
Tue, 5 Mar 2013 19:34:25 +0000 (19:34 +0000)
*  config/microblaze/microblaze-protos.h: Rename
microblaze_is_interrupt_handler to microblaze_is_interrupt_variant.
*  config/microblaze/microblaze.c (microblaze_attribute_table): Add
fast_interrupt.
(microblaze_fast_interrupt_function_p): New function.
(microblaze_is_interrupt_handler): Rename to
microblaze_is_interrupt_variant and add fast_interrupt check.
(microblaze_must_save_register): Use microblaze_is_interrupt_variant.
(save_restore_insns): Likewise.
(compute_frame_size): Likewise.
(microblaze_function_prologue): Add FAST_INTERRUPT_NAME.
(microblaze_globalize_label): Likewise.
*  config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME.
*  config/microblaze/microblaze.md: Use wrapper
microblaze_is_interrupt_variant.

From-SVN: r196474

gcc/ChangeLog
gcc/config/microblaze/microblaze-protos.h
gcc/config/microblaze/microblaze.c
gcc/config/microblaze/microblaze.h
gcc/config/microblaze/microblaze.md

index 2be47af74ad9105459f5437146b4446f1123c0f1..453c57b042fb1a8df73e619e04438bbcb9b80789 100644 (file)
@@ -1,3 +1,21 @@
+2013-03-05  David Holsgrove <david.holsgrove@xilinx.com>
+
+       *  config/microblaze/microblaze-protos.h: Rename
+       microblaze_is_interrupt_handler to microblaze_is_interrupt_variant.
+       *  config/microblaze/microblaze.c (microblaze_attribute_table): Add
+       fast_interrupt.
+       (microblaze_fast_interrupt_function_p): New function.
+       (microblaze_is_interrupt_handler): Rename to
+       microblaze_is_interrupt_variant and add fast_interrupt check.
+       (microblaze_must_save_register): Use microblaze_is_interrupt_variant.
+       (save_restore_insns): Likewise.
+       (compute_frame_size): Likewise.
+       (microblaze_function_prologue): Add FAST_INTERRUPT_NAME.
+       (microblaze_globalize_label): Likewise.
+       *  config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME.
+       *  config/microblaze/microblaze.md: Use wrapper
+       microblaze_is_interrupt_variant.
+
 2013-03-05  Kai Tietz  <ktietz@redhat.com>
 
        * sdbout.c (sdbout_one_type): Switch to current function's section
index fe2ac09f86ac09e7b731b1aa39524a42239c9d5d..e19939f0930757bc56eef8dcff35d167504c99c9 100644 (file)
@@ -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);
index 5286316e0ce299ef384f8081b93db26863f701a7..3a5299410b9651119fe86f9ab88e24f6162a162e 100644 (file)
@@ -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);
index c726978800dc444a78a9fbafc7cd34a946b67af8..8fbe5bf8085b9c179a873f35b86ebea774f1ba1f 100644 (file)
@@ -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.  */
 
index 78c033ee2f6f3ec6d0f91aa1676255d2eb0647ac..02857875022f9b79ecf84dd50b7092d683b3b7bd 100644 (file)
 (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
   [(any_return)]
   ""
   { 
-    if (microblaze_is_interrupt_handler ())
+    if (microblaze_is_interrupt_variant ())
         return "rtid\tr14, 0\;%#";
     else
         return "rtsd\tr15, 8\;%#";
    (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 \;%#";