diff mbox

Two C6X eh fixes

Message ID 4EA6D9E0.7070305@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt Oct. 25, 2011, 3:46 p.m. UTC
I've committed these two patches, which correct some problems where the
libgcc implementation didn't quite match the ABI.


Bernd

Index: libgcc/ChangeLog
===================================================================
--- libgcc/ChangeLog	(revision 180434)
+++ libgcc/ChangeLog	(working copy)
@@ -3,6 +3,9 @@
 	* config/c6x/pr-support.c (__gnu_unwind_24bit): Correct logic for the
 	case where B3 isn't the return register.
 
+	* config/c6x/pr-support.c (pop_compact_frame, pop_frame): Correct
+	logic for doubleword pops.
+
 2011-10-25  Andreas Tobler  <andreast@fgznet.ch>
 
 	* config/rs6000/t-freebsd: Add wildcard.
Index: libgcc/config/c6x/pr-support.c
===================================================================
--- libgcc/config/c6x/pr-support.c	(revision 180434)
+++ libgcc/config/c6x/pr-support.c	(working copy)
@@ -153,10 +153,7 @@ pop_compact_frame (_Unwind_Context * con
 {
   int size;
   _uw test;
-  int i;
-  int regno;
-  int regno2;
-  int nregs;
+  int i, regno, nregs;
 
   size = 0;
   nregs = __builtin_popcount (mask);
@@ -167,13 +164,11 @@ pop_compact_frame (_Unwind_Context * con
 	continue;
 
       regno = unwind_frame_regs[12 - i];
-      /* The last slot is a sigle word, so cannot store a register pair.  */
-      if (nregs > 2)
-	regno2 = unwind_frame_regs[13 - i];
-      else
-	regno2 = 0xff;
 
-      if ((mask & (test << 1)) != 0 && regno2 == regno + 1 && (regno & 1) == 0)
+      if (i < 12 && nregs > 2
+	  && (mask & (test << 1)) != 0
+	  && unwind_frame_regs[11 - i] == regno + 1
+	  && (regno & 1) == 0)
 	{
 	  i++;
 	  nregs--;
@@ -196,12 +191,11 @@ pop_compact_frame (_Unwind_Context * con
 	continue;
 
       regno = unwind_frame_regs[12 - i];
-      if (nregs > 2)
-	regno2 = unwind_frame_regs[13 - i];
-      else
-	regno2 = 0xff;
 
-      if ((mask & (test << 1)) != 0 && regno2 == regno + 1 && (regno & 1) == 0)
+      if (i < 12 && nregs > 2
+	  && (mask & (test << 1)) != 0
+	  && unwind_frame_regs[11 - i] == regno + 1
+	  && (regno & 1) == 0)
 	{
 	  /* Register pair.  */
 	  unwind_restore_pair (context, regno, ptr);
@@ -243,7 +237,7 @@ pop_frame (_Unwind_Context * context, _u
       if ((mask & (1 << i)) == 0)
 	continue;
       regno = unwind_frame_regs[12 - i];
-      if (i < 12 && unwind_frame_regs[13 - i] == (regno + 1)
+      if (i < 12 && unwind_frame_regs[11 - i] == (regno + 1)
 	  && (mask & (1 << (i + 1))) != 0
 	  && (((_uw)ptr) & 4) == 0
 	  && (regno & 1) == 0)
diff mbox

Patch

Index: libgcc/ChangeLog
===================================================================
--- libgcc/ChangeLog	(revision 180431)
+++ libgcc/ChangeLog	(working copy)
@@ -1,3 +1,8 @@ 
+2011-10-25  Bernd Schmidt  <bernds@codesourcery.com>
+
+	* config/c6x/pr-support.c (__gnu_unwind_24bit): Correct logic for the
+	case where B3 isn't the return register.
+
 2011-10-25  Andreas Tobler  <andreast@fgznet.ch>
 
 	* config/rs6000/t-freebsd: Add wildcard.
Index: libgcc/config/c6x/pr-support.c
===================================================================
--- libgcc/config/c6x/pr-support.c	(revision 180262)
+++ libgcc/config/c6x/pr-support.c	(working copy)
@@ -273,6 +273,14 @@  __gnu_unwind_24bit (_Unwind_Context * co
   _uw mask;
   _uw *ptr;
   _uw tmp;
+  int ret_reg = unwind_frame_regs[data & 0xf];
+
+  if (ret_reg != R_B3)
+    {
+      _Unwind_VRS_Get (context, _UVRSC_CORE, unwind_frame_regs[data & 0xf],
+		       _UVRSD_UINT32, &tmp);
+      _Unwind_VRS_Set (context, _UVRSC_CORE, R_B3, _UVRSD_UINT32, &tmp);
+    }
 
   mask = (data >> 4) & 0x1fff;
 
@@ -291,8 +299,7 @@  __gnu_unwind_24bit (_Unwind_Context * co
   else
     pop_frame (context, mask, ptr, offset != 0x7f);
 
-  _Unwind_VRS_Get (context, _UVRSC_CORE, unwind_frame_regs[data & 0xf],
-		   _UVRSD_UINT32, &tmp);
+  _Unwind_VRS_Get (context, _UVRSC_CORE, R_B3, _UVRSD_UINT32, &tmp);
   _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, &tmp);
 
   return _URC_OK;