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/RFA] SH: DWARF2 exception handling


Joern Rennecke <joern.rennecke@superh.com> wrote:
> TEMP should also be documented.  But that's just superficial -
> the design is broken (see below), and it is made to a questionable
> interface to start with - see my separate email titled
> "EH_RETURN_STACKADJ_RTX / EH_RETURN_DATA_REGNO vs. EH_RETURN_HANDLER_RTX /
> eh_return" that I've sent to the gcc mailing list.

I read that thread though I don't understand the Right Thing
to do. My implementation is only imitating the existing port.

>> dwarf2out.c:expand_builtin_init_dwarf_reg_sizes tests the result
>> of DWARF_FRAME_REGNUM, which is SH_DBX_REGISTER_NUMBER in our case,
>> for all numbers from 0 to (FIRST_PSEUDO_REGISTER - 1).
> 
> Then there should be a comment to that effect.

I'll add a comment

/* expand_builtin_init_dwarf_reg_sizes uses this for the existance test
   for register, so we should return -1 for the invalid register number.  */

just before the definition of DBX_REGISTER_NUMBER in sh.h.

> This breaks SH64, since PR_MEDIA_REG is saved as 64 bit there, and
> hence handled in the aligned case.
> I don't see why you would need to reorder the register saves; as
> you calculate the frame size anyway, you could also determine
> where exactly the PR register is.

Right. I stupidly used the way which non-SH5 does. How about
the attached one?

> Or if we can really rely on call-clobbered registers to live from
> __builtin_eh_return to the epilogue - they have to to get the values
> in EH_RETURN_STACKADJ_RTX and EH_RETURN_DATA_REGNO to / beyond the
> epilogue - we can just put the return address into a register -
> GPR for SHcompact, target register for SHmedia - and use that
> register in the epilogue.

GPR is used as the thread pointer in glibc already and I've
heard about another 3rd party's libraries for the embedded
systems which use GPR globally. It seems there is no remained
register for SHcompact. Of course, it's ok for SHmedia. 

Regards,
	kaz
--

--- ORIG/gccbib/gcc/config/sh/sh.c	Wed Nov  6 04:12:15 2002
+++ LOCAL/gccbib/gcc/config/sh/sh.c	Thu Nov 14 10:45:04 2002
@@ -4432,6 +4432,8 @@ calc_live_regs (count_ptr, live_regs_mas
 	   & ~ CALL_COOKIE_RET_TRAMP (1))
 	  || current_function_has_nonlocal_label))
     pr_live = 1;
+  if (current_function_calls_eh_return)
+    pr_live = 1;
   for (count = 0, reg = FIRST_PSEUDO_REGISTER - 1; reg >= 0; reg--)
     {
       if (reg == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG)
@@ -4446,7 +4448,12 @@ calc_live_regs (count_ptr, live_regs_mas
 	     && reg != RETURN_ADDRESS_POINTER_REGNUM
 	     && reg != T_REG && reg != GBR_REG)
 	  : (/* Only push those regs which are used and need to be saved.  */
-	     regs_ever_live[reg] && ! call_used_regs[reg]))
+	     (regs_ever_live[reg] && ! call_used_regs[reg])
+	     || (current_function_calls_eh_return
+		 && (reg == EH_RETURN_DATA_REGNO (0)
+		     || reg == EH_RETURN_DATA_REGNO (1)
+		     || reg == EH_RETURN_DATA_REGNO (2)
+		     || reg == EH_RETURN_DATA_REGNO (3)))))
 	{
 	  live_regs_mask[reg / 32] |= 1 << (reg % 32);
 	  count += GET_MODE_SIZE (REGISTER_NATURAL_MODE (reg));
@@ -5042,6 +5049,10 @@ sh_expand_epilogue ()
 		       + current_function_args_info.stack_regs * 8,
 		       stack_pointer_rtx, 7, emit_insn);
 
+  if (current_function_calls_eh_return)
+    emit_insn (GEN_ADD3 (stack_pointer_rtx, stack_pointer_rtx,
+			 EH_RETURN_STACKADJ_RTX));
+
   /* Switch back to the normal stack if necessary.  */
   if (sp_switch)
     emit_insn (gen_sp_switch_2 ());
@@ -5070,6 +5081,81 @@ sh_need_epilogue ()
       sh_need_epilogue_known = (epilogue == NULL ? -1 : 1);
     }
   return sh_need_epilogue_known > 0;
+}
+
+/* Emit code to change the current function's return address to RA.
+   TEMP is available as a scratch register, if needed.  */
+
+void
+sh_set_return_address (ra, tmp)
+     rtx ra, tmp;
+{
+  HOST_WIDE_INT live_regs_mask[(FIRST_PSEUDO_REGISTER + 31) / 32];
+  int d;
+  int d_rounding = 0;
+  int pr_offset;
+
+  calc_live_regs (&d, live_regs_mask);
+
+  if (TARGET_SH5)
+    {
+      int i;
+      int offset;
+      int align;
+      int pr_reg = TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG;
+      
+      if (d % (STACK_BOUNDARY / BITS_PER_UNIT))
+	d_rounding = ((STACK_BOUNDARY / BITS_PER_UNIT)
+		      - d % (STACK_BOUNDARY / BITS_PER_UNIT));
+
+      offset = 0;
+
+      /* We loop twice: first, we save 8-byte aligned registers in the
+	 higher addresses, that are known to be aligned.  Then, we
+	 proceed to saving 32-bit registers that don't need 8-byte
+	 alignment.  */
+      for (align = 0; align <= 1; align++)
+	for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+	  if (live_regs_mask[i/32] & (1 << (i % 32)))
+	    {
+	      enum machine_mode mode = REGISTER_NATURAL_MODE (i);
+
+	      if (mode == SFmode && (i % 2) == 0
+		  && ! TARGET_FPU_SINGLE && FP_REGISTER_P (i)
+		  && (live_regs_mask[(i ^ 1) / 32] & (1 << ((i ^ 1) % 32))))
+		{
+		  mode = DFmode;
+		  i++;
+		}
+
+	      /* If we're doing the aligned pass and this is not aligned,
+		 or we're doing the unaligned pass and this is aligned,
+		 skip it.  */
+	      if ((GET_MODE_SIZE (mode) % (STACK_BOUNDARY / BITS_PER_UNIT)
+		   == 0) != align)
+		continue;
+
+	      if (i == pr_reg)
+		goto found;
+
+	      offset += GET_MODE_SIZE (mode);
+	    }
+
+      /* We can't find pr register.  */
+      abort ();
+
+    found:
+      pr_offset = (rounded_frame_size (d) - d_rounding + offset
+		   + SHMEDIA_REGS_STACK_ADJUST ());
+    }
+  else
+    pr_offset = rounded_frame_size (d) - d_rounding;
+
+  emit_insn (GEN_MOV (tmp, GEN_INT (pr_offset)));
+  emit_insn (GEN_ADD3 (tmp, tmp, frame_pointer_rtx));
+
+  tmp = gen_rtx_MEM (Pmode, tmp);
+  emit_insn (GEN_MOV (tmp, ra));
 }
 
 /* Clear variables at function end.  */


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