diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 515e4f97d2139276d9298562875e83186bf2e1c1..030f172173d9bd35b02eff37337a724f09f59958 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2006-09-19  Paul Brook  <paul@codesourcery.com>
+
+	PR target/28516
+	* config/arm/arm.c (arm_unwind_emit_set): Handle reg = sp + const.
+
 2006-09-17  Zdenek Dvorak <dvorakz@suse.cz>
 
 	PR tree-optimization/28887
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a36c0d791760a80f655959c86681fb9ef131945c..ff5831f4325e75bf28f5f714ac9956d8f42c6038 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -15415,6 +15415,15 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
 	  /* Move from sp to reg.  */
 	  asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0));
 	}
+     else if (GET_CODE (e1) == PLUS
+	      && GET_CODE (XEXP (e1, 0)) == REG
+	      && REGNO (XEXP (e1, 0)) == SP_REGNUM
+	      && GET_CODE (XEXP (e1, 1)) == CONST_INT)
+	{
+	  /* Set reg to offset from sp.  */
+	  asm_fprintf (asm_out_file, "\t.movsp %r, #%d\n",
+		       REGNO (e0), (int)INTVAL(XEXP (e1, 1)));
+	}
       else
 	abort ();
       break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f5d9a7a452cb673ee71d905b04a3293387d2e3f3..e643d1d500108fbc4f83392958d3c45b9770ee28 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-09-19  Paul Brook  <paul@codesourcery.com>
+
+	PR target/28516
+	* gcc.dg/nested-func-5.c: New test.
+
 2006-09-19  Ben Elliston  <bje@au.ibm.com>
 
 	* lib/target-supports.exp (check_effective_target_tls): Compile
diff --git a/gcc/testsuite/gcc.dg/nested-func-5.c b/gcc/testsuite/gcc.dg/nested-func-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..5076dbd50497a72bf1cc8bfa90bee73bcf97205d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/nested-func-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fexceptions" } */
+/* PR28516: ICE generating ARM unwind directives for nested functions.  */
+
+void ex(int (*)(void));
+void foo(int i)
+{
+  int bar(void)
+  {
+    return i;
+  }
+  ex(bar);
+}