diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f458ac7b176f6487c43c29357efafe7c3fafbbf4..ad824be9af5cabc1106bb72000a5aac95b7d6ef7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2007-02-05  Richard Sandiford  <richard@codesourcery.com>
+
+	* doc/tm.texi (DWARF_ALT_FRAME_RETURN_COLUMN): Do not require
+	DWARF_FRAME_RETURN_COLUMN to be a general register.
+	* dwarf2out.c (init_return_column_size): New function, split from...
+	(expand_builtin_init_dwarf_reg_sizes): ...here.  Allow both
+	DWARF_FRAME_RETURN_COLUMN and DWARF_ALT_FRAME_RETURN_COLUMN
+	to be nongeneral registers.
+	* config/m68k/m68k.h (DWARF_FRAME_REGNUM): Only map FP and
+	integer registers.
+	(DWARF_FRAME_REGISTERS, DWARF_FRAME_RETURN_COLUMN): Define.
+	(DWARF_ALT_FRAME_RETURN_COLUMN): Define.
+
 2007-02-04  Zdenek Dvorak <dvorakz@suse.cz>
 
 	* cfgcleanup.c (try_optimize_cfg): Avoid removing ENTRY_BLOCK_PTR.
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 39a5878089714f1f208389ac254cc11b363cc7c2..d832564147582574283bc29f5093a842734c4358 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -1092,7 +1092,15 @@ do { if (cc_prev_status.flags & CC_IN_68881)			\
 /* We must not use the DBX register numbers for the DWARF 2 CFA column
    numbers because that maps to numbers beyond FIRST_PSEUDO_REGISTER.
    Instead use the identity mapping.  */
-#define DWARF_FRAME_REGNUM(REG) REG
+#define DWARF_FRAME_REGNUM(REG) \
+  (INT_REGNO_P (REG) || FP_REGNO_P (REG) ? (REG) : INVALID_REGNUM)
+
+/* The return column was originally 24, but gcc used 25 for a while too.
+   Define both registers 24 and 25 as Pmode ones and use 24 in our own
+   unwind information.  */
+#define DWARF_FRAME_REGISTERS 25
+#define DWARF_FRAME_RETURN_COLUMN 24
+#define DWARF_ALT_FRAME_RETURN_COLUMN 25
 
 /* Before the prologue, the top of the frame is at 4(%sp).  */
 #define INCOMING_FRAME_SP_OFFSET 4
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 7c2eca5df09120bfbae01a9c2f0478fe5a5a0b6a..c9f6cb89d47a64a1847392a1d1310203a60a58f8 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3092,10 +3092,14 @@ If this RTL is a @code{REG}, you should also define
 
 @defmac DWARF_ALT_FRAME_RETURN_COLUMN
 A C expression whose value is an integer giving a DWARF 2 column
-number that may be used as an alternate return column.  This should
-be defined only if @code{DWARF_FRAME_RETURN_COLUMN} is set to a
-general register, but an alternate column needs to be used for
-signal frames.
+number that may be used as an alternative return column.  The column
+must not correspond to any gcc hard register (that is, it must not
+be in the range of @code{DWARF_FRAME_REGNUM}).
+
+This macro can be useful if @code{DWARF_FRAME_RETURN_COLUMN} is set to a
+general register, but an alternative column needs to be used for signal
+frames.  Some targets have also used different frame return columns
+over time.
 @end defmac
 
 @defmac DWARF_ZERO_REG
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 861ede5f95af5a5e58db1f70f03f1434e29140bc..6cbf9d3874d4675c72de813a679b5772ebd33c21 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -443,6 +443,17 @@ stripattributes (const char *s)
   return stripped;
 }
 
+/* MEM is a memory reference for the register size table, each element of
+   which has mode MODE.  Initialize column C as a return address column.  */
+
+static void
+init_return_column_size (enum machine_mode mode, rtx mem, unsigned int c)
+{
+  HOST_WIDE_INT offset = c * GET_MODE_SIZE (mode);
+  HOST_WIDE_INT size = GET_MODE_SIZE (Pmode);
+  emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+}
+
 /* Generate code to initialize the register size table.  */
 
 void
@@ -481,21 +492,12 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
 	}
     }
 
+  if (!wrote_return_column)
+    init_return_column_size (mode, mem, DWARF_FRAME_RETURN_COLUMN);
+
 #ifdef DWARF_ALT_FRAME_RETURN_COLUMN
-  gcc_assert (wrote_return_column);
-  i = DWARF_ALT_FRAME_RETURN_COLUMN;
-  wrote_return_column = false;
-#else
-  i = DWARF_FRAME_RETURN_COLUMN;
+  init_return_column_size (mode, mem, DWARF_ALT_FRAME_RETURN_COLUMN);
 #endif
-
-  if (! wrote_return_column)
-    {
-      enum machine_mode save_mode = Pmode;
-      HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode);
-      HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
-      emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
-    }
 }
 
 /* Convert a DWARF call frame info. operation to its string name */