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


> -----Original Message-----
> From: Joern Rennecke [mailto:joern.rennecke@superh.com]
> Sent: Thursday, August 12, 2004 6:21 PM
> To: Asgari J. Jinia
> Cc: Joern Rennecke; gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH - SH] trap_exit and sp_switch with 
> interrupt_handler
> attribute

> Constant loads are fixed up in sh_reorg.  Thus, emitting
> a load of a symol_ref directly into a register does not work in
> an output template.  I suggest that you change the pattern into a
> define_expand or define_insn_and_split, so that the load is exposed
> to sh_reorg.
> 

Reference:
http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00752.html
  
Sorry for late answer.
In following patch I have tried to correct sp_switch insn. I have to add
"global_regs[0] = 1;" in the sp_switch2 insn because with "-O2" option
compiler removes popping of r0 register from the epilogue.

------------------------------------------------------------------------------
gcc\ChangeLog:
2004-11-24  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.
	(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.


--- gcc-3.4.2/gcc/config/sh/sh.c.orig	2004-10-20 15:23:55.000000000 +0530
+++ gcc-3.4.2/gcc/config/sh/sh.c	2004-11-19 18:34:03.000000000 +0530
@@ -204,6 +204,7 @@ static rtx mark_constant_pool_use (rtx);
 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 +5316,7 @@ sh_expand_prologue (void)
     }
 
   /* 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 +5820,7 @@ sh_expand_epilogue (bool sibcall_p)
 			 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.  */
@@ -6825,6 +6826,7 @@ sh_insert_attributes (tree node, tree *a
   if (! pragma_interrupt
       || TREE_CODE (node) != FUNCTION_DECL)
     return;
+  pragma_interrupt = 0;
 
   /* We are only interested in fields.  */
   if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd')
@@ -6884,6 +6886,27 @@ sh_handle_interrupt_handler_attribute (t
   return NULL_TREE;
 }
 
+/* True if __attribute__((sp_switch)), for the current function.  */
+static int
+sh_cfun_sp_switch_handler_p (void)
+{
+  tree t;
+  t = lookup_attribute ("sp_switch",
+                        DECL_ATTRIBUTES (current_function_decl));
+  if (t != NULL_TREE)
+    {
+      sp_switch = gen_rtx_SYMBOL_REF (VOIDmode,
+                                      TREE_STRING_POINTER (TREE_VALUE(TREE_VALUE (t))));
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+
+
 /* Handle an "sp_switch" attribute; arguments as in
    struct attribute_spec.handler.  */
 static tree
@@ -6896,7 +6919,8 @@ sh_handle_sp_switch_attribute (tree *nod
 	       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 +6934,6 @@ sh_handle_sp_switch_attribute (tree *nod
 	       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-09-30 15:51:18.000000000 +0530
+++ gcc-3.4.2/gcc/config/sh/sh.md	2004-10-20 15:21:33.000000000 +0530
@@ -9436,27 +9436,40 @@ mov.l\\t1f,r0\\n\\
   "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,0);
+  xoperand[1] = gen_rtx_REG (SImode,0);
+  xoperand[1] = gen_rtx_MEM (SImode,xoperand[1]);
+  
+  emit_insn (gen_push (xoperand[0]));
+  emit_insn (gen_movsi_i (xoperand[0],sp_switch));
+  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)));
+  global_regs[0] = 1;
+  emit_insn (gen_pop (gen_rtx_REG (SImode,0)));   
+  DONE;}")
+
 
 ;; Integer vector moves
-----------------------------------------------------------------
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]