This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [PATCH - SH] trap_exit and sp_switch with interrupt_handler attribute


Thanks for your comments.

> That doesn't look right.  Try to use EPILOGUE_USES instead.

Done.

> You still have the side effect of setting sp_switch in a 'predicate'
> function.  Please make sp_switch_1 look up the attribute 
> instead, and remove
> the sp_switch variable.

Now I have removed sp_switch global variable and defined a function to return
rtx for sp_switch parameter.

--------------------------------------------------------
gcc\ChangeLog:
2004-12-06  Asgari Jinia  <asgarij@kpitcummins.com>

      * config/sh/sh.c (sh_cfun_sp_switch_handler_p): Added.
      Returns true if current function has sp_switch attribute.
      (sp_switch): Deleted.
	(sh_expand_prologue): Use sh_cfun_sp_switch_handler_p for checking 
      'sp_switch' attribute.
	(sh_insert_attributes): Reset pragma_interrupt
	(sh_handle_sp_switch_attribute): Use 'lookup_attribute' function to 
      check interrupt_handler attribute.
      (gen_sp_switch_rtx): Added. Returns rtx of sp_switch attribute's
      parameter.
      * config/sh/sh.h (EPILOGUE_USES): Added R0_REG.
      * config/sh/sh-protos.h (gen_sp_switch_rtx): Declare.

--- gcc-3.4.2/gcc/config/sh/sh.c.orig	2004-12-06 13:21:09.000000000 +0530
+++ gcc-3.4.2/gcc/config/sh/sh.c	2004-12-06 13:57:54.000000000 +0530
@@ -76,11 +76,6 @@
    (instead of an rte instruction).  */
 int trap_exit;
 
-/* This is used by the sp_switch attribute for functions.  It specifies
-   a variable holding the address of the stack the interrupt function
-   should switch to/from at entry/exit.  */
-rtx sp_switch;
-
 /* This is set by #pragma trapa, and is similar to the above, except that
    the compiler doesn't emit code to preserve all registers.  */
 static int pragma_trapa;
@@ -204,6 +199,7 @@
 const struct attribute_spec sh_attribute_table[];
 static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, int, bool *);
 static tree sh_handle_sp_switch_attribute (tree *, tree, tree, int, bool *);
+static int sh_cfun_sp_switch_handler_p (void);
 static tree sh_handle_trap_exit_attribute (tree *, tree, tree, int, bool *);
 static tree sh_handle_renesas_attribute (tree *, tree, tree, int, bool *);
 static void sh_output_function_epilogue (FILE *, HOST_WIDE_INT);
@@ -5315,7 +5311,7 @@
     }
 
   /* If we're supposed to switch stacks at function entry, do so now.  */
-  if (sp_switch)
+  if (sh_cfun_sp_switch_handler_p)
     emit_insn (gen_sp_switch_1 ());
 
   d = calc_live_regs (&live_regs_mask);
@@ -5819,7 +5815,7 @@
 			 EH_RETURN_STACKADJ_RTX));
 
   /* Switch back to the normal stack if necessary.  */
-  if (sp_switch)
+  if (sh_cfun_sp_switch_handler_p)
     emit_insn (gen_sp_switch_2 ());
 
   /* Tell flow the insn that pops PR isn't dead.  */
@@ -5923,7 +5919,6 @@
 {
   trap_exit = pragma_interrupt = pragma_trapa = pragma_nosave_low_regs = 0;
   sh_need_epilogue_known = 0;
-  sp_switch = NULL_RTX;
 }
 
 static rtx
@@ -6826,6 +6821,8 @@
       || TREE_CODE (node) != FUNCTION_DECL)
     return;
 
+  pragma_interrupt = 0;
+  
   /* We are only interested in fields.  */
   if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd')
     return;
@@ -6884,6 +6881,27 @@
   return NULL_TREE;
 }
 
+/* generates rtx of sp_switch's parameter. */
+rtx
+gen_sp_switch_rtx (void)
+{
+  tree t;
+  t = lookup_attribute ("sp_switch",
+                        DECL_ATTRIBUTES (current_function_decl));
+  return gen_rtx_SYMBOL_REF (VOIDmode,
+                             TREE_STRING_POINTER (TREE_VALUE(TREE_VALUE (t))));
+
+}
+
+/* True if __attribute__((sp_switch)), for the current function.  */
+static int
+sh_cfun_sp_switch_handler_p (void)
+{
+  return (lookup_attribute ("sp_switch",
+                DECL_ATTRIBUTES (current_function_decl))
+      != NULL_TREE);
+}
+
 /* Handle an "sp_switch" attribute; arguments as in
    struct attribute_spec.handler.  */
 static tree
@@ -6896,7 +6914,8 @@
 	       IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
-  else if (!pragma_interrupt)
+  else if (lookup_attribute ("interrupt_handler",
+                             DECL_ATTRIBUTES (*node)) == NULL) 
     {
       /* The sp_switch attribute only has meaning for interrupt functions.  */
       warning ("`%s' attribute only applies to interrupt functions",
@@ -6910,11 +6929,6 @@
 	       IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
-  else
-    {
-      sp_switch = gen_rtx_SYMBOL_REF (VOIDmode,
-				      TREE_STRING_POINTER (TREE_VALUE (args)));
-    }
 
   return NULL_TREE;
 }

--- gcc-3.4.2/gcc/config/sh/sh.md.orig	2004-12-06 13:21:09.000000000 +0530
+++ gcc-3.4.2/gcc/config/sh/sh.md	2004-12-06 17:09:03.000000000 +0530
@@ -9436,27 +9436,38 @@
   "fmov{.s|}	@(%0,%1),%2")
 
 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
-(define_insn "sp_switch_1"
+(define_expand "sp_switch_1"
   [(const_int 1)]
   "TARGET_SH1"
-  "*
+  "
 {
-  rtx xoperands[1];
+  rtx xoperand[2];
+  
+  xoperand[0] = gen_rtx_REG (SImode,R0_REG);
+  xoperand[1] = gen_rtx_REG (SImode,R0_REG);
+  xoperand[1] = gen_rtx_MEM (SImode,xoperand[1]);
+  
+  emit_insn (gen_push (xoperand[0]));
+  emit_insn (gen_movsi_i (xoperand[0],gen_sp_switch_rtx ()));
+  emit_insn (gen_movsi_i (xoperand[0],xoperand[1]));  
+  emit_insn (gen_movsi_i (gen_rtx_MEM (SImode,gen_rtx (PRE_DEC,SImode,xoperand[0])),
+                          gen_rtx_REG (SImode,SP_REG)));
+  emit_insn (gen_movsi_i (gen_rtx_REG (SImode,SP_REG),xoperand[0]));
+    
+  DONE;}")
 
-  xoperands[0] = sp_switch;
-  output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
-  output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
-  return \"mov r0,r15\";
-}"
-  [(set_attr "length" "10")])
 
 ;; Switch back to the original stack for interrupt functions with the
 ;; sp_switch attribute.  */
-(define_insn "sp_switch_2"
+(define_expand "sp_switch_2"
   [(const_int 2)]
   "TARGET_SH1"
-  "mov.l @r15+,r15\;mov.l @r15+,r0"
-  [(set_attr "length" "4")])
+  "
+{
+  emit_insn (gen_pop (gen_rtx_REG (SImode,SP_REG)));
+  emit_insn (gen_pop (gen_rtx_REG (SImode,R0_REG)));   
+  DONE;}")
+
 
 ;; Integer vector moves
 
 
 
--- gcc-3.4.2/gcc/config/sh/sh-protos.h.orig	2004-12-06 13:21:09.000000000 +0530
+++ gcc-3.4.2/gcc/config/sh/sh-protos.h	2004-12-06 13:21:09.000000000 +0530
@@ -26,7 +26,7 @@
 
 #ifdef RTX_CODE
 extern struct rtx_def *prepare_scc_operands (enum rtx_code);
-
+extern rtx gen_sp_switch_rtx (void);
 /* Declare functions defined in sh.c and used in templates.  */
 
 extern const char *output_branch (int, rtx, rtx *);
--- gcc-3.4.2/gcc/config/sh/sh.h.orig	2004-12-06 13:48:01.000000000 +0530
+++ gcc-3.4.2/gcc/config/sh/sh.h	2004-12-06 15:11:23.000000000 +0530
@@ -3122,10 +3122,6 @@
 
 extern int current_function_interrupt;
 
-/* Set to an RTX containing the address of the stack to switch to
-   for interrupt functions.  */
-extern struct rtx_def *sp_switch;
-
 extern int rtx_equal_function_value_matters;
 
 
@@ -3235,8 +3231,8 @@
 #define MODE_EXIT(ENTITY) \
   (sh_cfun_attr_renesas_p () ? FP_MODE_NONE : NORMAL_MODE (ENTITY))
 
-#define EPILOGUE_USES(REGNO)       ((TARGET_SH2E || TARGET_SH4)		\
-				    && (REGNO) == FPSCR_REG)
+#define EPILOGUE_USES(REGNO)       (((TARGET_SH2E || TARGET_SH4)		\
+				    && (REGNO) == FPSCR_REG) || (REGNO) == R0_REG)
 
 #define MODE_NEEDED(ENTITY, INSN)					\
   (recog_memoized (INSN) >= 0						\

--------------------------------------------------------
Regards,
Asgari Jinia
KPIT Cummins InfoSystems Ltd.
Pune, India

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Free download of GNU based tool-chains for Renesas' SH and H8 Series.
The following site also offers free technical support to its users. 
Visit http://www.kpitgnutools.com for details. 
Latest versions of KPIT GNU tools are released on Oct 1, 2004.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]