diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5d739cce83d1d48a677ae0c8e2da8c94fa27eed..8b4ebf3c8ebf109cece12c6d58163653b70d5182 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+Sat May 19 18:23:04 2001  Richard Henderson <rth@redhat.com>
+
+	* except.c (dw2_build_landing_pads): Use word_mode, not Pmode,
+	as ncessary.
+	(expand_eh_return): Convert between word_mode and Pmode.
+	* unwind-dw2.c (extract_cie_info): Do not assume words and pointers
+	are the same size.
+	(execute_stack_op): Likewise.
+	(execute_cfa_program): Likewise.
+	(uw_frame_state_for): Likewise.
+	(uw_update_context_1): Likewise.
+	* unwind.inc (_Unwind_Reason_Code): Likewise.
+	* config/mips/mips.h (EH_RETURN_DATA_REGNO): Define.
+	(EH_RETURN_STACKADJ_RTX): Likewise.
+	* config/mips/mips.c (compute_frame_size): Make space for saving
+	EH return registers.
+	(mips_expand_epilogue): Handle EH stack adjustments.
+	* config/mips/mips.md (eh_return): New pattern.
+	(eh_set_lr_si): Likewise.
+	(eh_set_lr_di): Likewise.
+	Add splitter to perform EH return after reload.
+		
 2001-05-19  Mark Mitchell  <mark@codesourcery.com>
 
 	* jump.c (mark_jump_label): Tidy previous change.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index f20813772593bddbb63f2137e2291fd78d6bd91b..c90857e3050e62d9d97246c6d72d8fbd202a3231 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -6244,6 +6244,20 @@ compute_frame_size (size)
 	}
     }
 
+  /* We need to restore these for the handler.  */
+  if (current_function_calls_eh_return)
+    {
+      int i;
+      for (i = 0; ; ++i)
+	{
+	  regno = EH_RETURN_DATA_REGNO (i);
+	  if (regno == INVALID_REGNUM)
+	    break;
+	  gp_reg_size += GET_MODE_SIZE (gpr_mode);
+	  mask |= 1L << (regno - GP_REG_FIRST);
+	}
+    }
+
   /* Calculate space needed for fp registers.  */
   if (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT)
     {
@@ -7534,13 +7548,27 @@ mips_expand_epilogue ()
       if (tsize > 32767 && TARGET_MIPS16)
 	abort ();
 
+      if (current_function_calls_eh_return)
+	{
+	  rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
+	  if (Pmode == DImode)
+	    emit_insn (gen_adddi3 (eh_ofs, eh_ofs, tsize_rtx));
+	  else
+	    emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
+	  tsize_rtx = eh_ofs;
+	}
+
       emit_insn (gen_blockage ());
-      if (Pmode == DImode && tsize != 0)
-	emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
-			       tsize_rtx));
-      else if (tsize != 0)
-	emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
-			       tsize_rtx));
+
+      if (tsize != 0 || current_function_calls_eh_return)
+	{
+	  if (Pmode == DImode)
+	    emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
+				   tsize_rtx));
+	  else
+	    emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+				   tsize_rtx));
+	}
     }
 
   /* The mips16 loads the return address into $7, not $31.  */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 08f35fa7c2de7cedfb361dae692c6ceee0151f36..3d3ea807fbd8cf2c5e25daac53b1d0cdf4953db4 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1105,6 +1105,10 @@ while (0)
 /* Before the prologue, RA lives in r31.  */
 #define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)
 
+/* Describe how we implement __builtin_eh_return.  */
+#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
+
 /* Overrides for the COFF debug format.  */
 #define PUT_SDB_SCL(a)					\
 do {							\
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 31ee4d63c29cf7b44e5f0f9374600888efe452f2..5b8d00e92888fbd83bf999c9e75dbb25fef9177e 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -26,6 +26,26 @@
 ;; ??? Currently does not have define_function_unit support for the R8000.
 ;; Must include new entries for fmadd in addition to existing entries.
 
+;; UNSPEC values used in mips.md
+;; Number	USE
+;; 0		movsi_ul
+;; 1		movsi_us, get_fnaddr
+;; 2		loadgp
+;; 3		eh_set_return
+;; 20		builtin_setjmp_setup
+;;
+;; UNSPEC_VOLATILE values
+;; 0		blockage
+;; 3		builtin_longjmp
+;; 10		consttable_qi
+;; 11		consttable_hi
+;; 12		consttable_si
+;; 13		consttable_di
+;; 14		consttable_sf
+;; 15		consttable_df
+;; 16		align_2
+;; 17		align_4
+;; 18		align_8
 
 
 ;; ....................
@@ -9484,6 +9504,73 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j\\t%2"
    (set_attr "mode"	"none")
    (set_attr "length"	"16")])
 
+;; This is used in compiling the unwind routines.
+(define_expand "eh_return"
+  [(use (match_operand 0 "general_operand" ""))
+   (use (match_operand 1 "general_operand" ""))]
+  ""
+  "
+{
+  enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
+
+  if (GET_MODE (operands[1]) != gpr_mode)
+    operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
+  if (TARGET_64BIT)
+    emit_insn (gen_eh_set_lr_di (operands[1]));
+  else
+    emit_insn (gen_eh_set_lr_si (operands[1]));
+
+  emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
+  DONE;
+}")
+
+;; Clobber the return address on the stack.  We can't expand this
+;; until we know where it will be put in the stack frame.
+
+(define_insn "eh_set_lr_si"
+  [(unspec [(match_operand:SI 0 "register_operand" "r")] 3)
+   (clobber (match_scratch:SI 1 "=&r"))]
+  "! TARGET_64BIT"
+  "#")
+
+(define_insn "eh_set_lr_di"
+  [(unspec [(match_operand:DI 0 "register_operand" "r")] 3)
+   (clobber (match_scratch:DI 1 "=&r"))]
+  "TARGET_64BIT"
+  "#")
+
+(define_split
+  [(unspec [(match_operand 0 "register_operand" "r")] 3)
+   (clobber (match_scratch 1 "=&r"))]
+  "reload_completed"
+  [(const_int 0)]
+  "
+{
+  HOST_WIDE_INT gp_offset;
+  rtx base;
+
+  compute_frame_size (get_frame_size ());
+  if (((current_frame_info.mask >> 31) & 1) == 0)
+    abort ();
+  gp_offset = current_frame_info.gp_sp_offset;
+
+  if (gp_offset < 32768)
+    base = stack_pointer_rtx;
+  else
+    {
+      base = operands[1];
+      emit_move_insn (base, GEN_INT (gp_offset));
+      if (Pmode == DImode)
+	emit_insn (gen_adddi3 (base, base, stack_pointer_rtx));
+      else
+	emit_insn (gen_addsi3 (base, base, stack_pointer_rtx));
+      gp_offset = 0;
+    }
+  emit_move_insn (gen_rtx_MEM (GET_MODE (operands[0]),
+			       plus_constant (base, gp_offset)),
+		  operands[0]);
+  DONE;
+}")
 
 ;;
 ;;  ....................
diff --git a/gcc/except.c b/gcc/except.c
index 48efbf9b8fc48ed5be7bd4a57b5d8be94bb2b1e1..c7493e7d9306c48f835bf5f1ed80e3e7c411bbb7 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1897,7 +1897,7 @@ dw2_build_landing_pads ()
       emit_move_insn (cfun->eh->exc_ptr,
 		      gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0)));
       emit_move_insn (cfun->eh->filter,
-		      gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (1)));
+		      gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
 
       seq = get_insns ();
       end_sequence ();
@@ -3035,6 +3035,8 @@ expand_eh_return ()
   else
 #endif
     {
+      rtx handler;
+
       ra = EH_RETURN_HANDLER_RTX;
       if (! ra)
 	{
@@ -3043,7 +3045,17 @@ expand_eh_return ()
 	}
 
       emit_move_insn (sa, cfun->eh->ehr_stackadj);
-      emit_move_insn (ra, cfun->eh->ehr_handler);
+
+      handler = cfun->eh->ehr_handler;
+      if (GET_MODE (ra) != Pmode)
+	{
+#ifdef POINTERS_EXTEND_UNSIGNED
+	  handler = convert_memory_address (GET_MODE (ra), handler);
+#else
+	  handler = convert_to_mode (GET_MODE (ra), handler, 0);
+#endif
+	}
+      emit_move_insn (ra, handler);
     }
 
   emit_label (around_label);
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 20deb5721f9a15638f8f3042a9faa324526fcbf7..3011bc7341f396fad76227b90f2794c9b450911a 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -218,15 +218,12 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
   const unsigned char *aug = cie->augmentation;
   const unsigned char *p = aug + strlen (aug) + 1;
   const unsigned char *ret = NULL;
-  _Unwind_Word code_align;
-  _Unwind_Sword data_align;
+  _Unwind_Ptr tmp;
 
   /* Immediately following the augmentation are the code and
      data alignment and return address column.  */
-  p = read_uleb128 (p, &code_align);
-  p = read_sleb128 (p, &data_align);
-  fs->code_align = code_align;
-  fs->data_align = data_align;
+  p = read_uleb128 (p, &tmp); fs->code_align = tmp;
+  p = read_sleb128 (p, &tmp); fs->data_align = (saddr) tmp;
   fs->retaddr_column = *p++;
   fs->lsda_encoding = DW_EH_PE_omit;
 
@@ -235,9 +232,8 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
      the size.  */
   if (*aug == 'z')
     {
-      _Unwind_Word i;
-      p = read_uleb128 (p, &i);
-      ret = p + i;
+      p = read_uleb128 (p, &tmp);
+      ret = p + tmp;
 
       fs->saw_z = 1;
       ++aug;
@@ -303,6 +299,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
       enum dwarf_location_atom op = *op_ptr++;
       _Unwind_Word result, reg;
       _Unwind_Sword offset;
+      _Unwind_Ptr ptrtmp;
 
       switch (op)
 	{
@@ -379,11 +376,12 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
 	  op_ptr += 8;
 	  break;
 	case DW_OP_constu:
-	  op_ptr = read_uleb128 (op_ptr, &result);
+	  op_ptr = read_uleb128 (op_ptr, &ptrtmp);
+	  result = ptrtmp;
 	  break;
 	case DW_OP_consts:
-	  op_ptr = read_sleb128 (op_ptr, &offset);
-	  result = offset;
+	  op_ptr = read_sleb128 (op_ptr, &ptrtmp);
+	  result = (saddr)ptrtmp;
 	  break;
 
 	case DW_OP_reg0:
@@ -421,7 +419,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
 	  result = _Unwind_GetGR (context, op - DW_OP_reg0);
 	  break;
 	case DW_OP_regx:
-	  op_ptr = read_uleb128 (op_ptr, &reg);
+	  op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
 	  result = _Unwind_GetGR (context, reg);
 	  break;
 
@@ -457,12 +455,12 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
 	case DW_OP_breg29:
 	case DW_OP_breg30:
 	case DW_OP_breg31:
-	  op_ptr = read_sleb128 (op_ptr, &offset);
+	  op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
 	  result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
 	  break;
 	case DW_OP_bregx:
-	  op_ptr = read_uleb128 (op_ptr, &reg);
-	  op_ptr = read_sleb128 (op_ptr, &offset);
+	  op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
+	  op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
 	  result = _Unwind_GetGR (context, reg) + offset;
 	  break;
 
@@ -559,7 +557,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
 	      result = ~result;
 	      break;
 	    case DW_OP_plus_uconst:
-	      op_ptr = read_uleb128 (op_ptr, &reg);
+	      op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
 	      result += reg;
 	      break;
 	    }
@@ -698,16 +696,17 @@ execute_cfa_program (const unsigned char *insn_ptr,
   while (insn_ptr < insn_end && fs->pc < context->ra)
     {
       unsigned char insn = *insn_ptr++;
-      _Unwind_Word reg, uoffset;
+      _Unwind_Word reg;
       _Unwind_Sword offset;
+      _Unwind_Ptr ptrtmp;
 
       if (insn & DW_CFA_advance_loc)
 	fs->pc += (insn & 0x3f) * fs->code_align;
       else if (insn & DW_CFA_offset)
 	{
 	  reg = insn & 0x3f;
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
-	  offset = (_Unwind_Sword)uoffset * fs->data_align;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  offset = ptrtmp * fs->data_align;
 	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
 	  fs->regs.reg[reg].loc.offset = offset;
 	}
@@ -724,28 +723,28 @@ execute_cfa_program (const unsigned char *insn_ptr,
 	  break;
 
 	case DW_CFA_advance_loc1:
-	  fs->pc += read_1u (insn_ptr);
+	  fs->pc += read_1u (insn_ptr) * fs->code_align;
 	  insn_ptr += 1;
 	  break;
 	case DW_CFA_advance_loc2:
-	  fs->pc += read_2u (insn_ptr);
+	  fs->pc += read_2u (insn_ptr) * fs->code_align;
 	  insn_ptr += 2;
 	  break;
 	case DW_CFA_advance_loc4:
-	  fs->pc += read_4u (insn_ptr);
+	  fs->pc += read_4u (insn_ptr) * fs->code_align;
 	  insn_ptr += 4;
 	  break;
 
 	case DW_CFA_offset_extended:
-	  insn_ptr = read_uleb128 (insn_ptr, &reg);
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
-	  offset = (_Unwind_Sword)uoffset * fs->data_align;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  offset = ptrtmp * fs->data_align;
 	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
 	  fs->regs.reg[reg].loc.offset = offset;
 	  break;
 
 	case DW_CFA_restore_extended:
-	  insn_ptr = read_uleb128 (insn_ptr, &reg);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
 	  fs->regs.reg[reg].how = REG_UNSAVED;
 	  break;
 
@@ -757,8 +756,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
 	case DW_CFA_register:
 	  {
 	    _Unwind_Word reg2;
-	    insn_ptr = read_uleb128 (insn_ptr, &reg);
-	    insn_ptr = read_uleb128 (insn_ptr, &reg2);
+	    insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	    insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
 	    fs->regs.reg[reg].how = REG_SAVED_REG;
 	    fs->regs.reg[reg].loc.reg = reg2;
 	  }
@@ -790,55 +789,60 @@ execute_cfa_program (const unsigned char *insn_ptr,
 	  break;
 
 	case DW_CFA_def_cfa:
-	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
-	  fs->cfa_offset = uoffset;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = ptrtmp;
 	  fs->cfa_how = CFA_REG_OFFSET;
 	  break;
 
 	case DW_CFA_def_cfa_register:
-	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_reg = ptrtmp;
 	  fs->cfa_how = CFA_REG_OFFSET;
 	  break;
 
 	case DW_CFA_def_cfa_offset:
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
-	  fs->cfa_offset = uoffset;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = ptrtmp;
 	  /* cfa_how deliberately not set.  */
 	  break;
 
 	case DW_CFA_def_cfa_expression:
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
 	  fs->cfa_exp = insn_ptr;
 	  fs->cfa_how = CFA_EXP;
-	  insn_ptr += uoffset;
+	  insn_ptr += ptrtmp;
 	  break;
 
 	case DW_CFA_expression:
-	  insn_ptr = read_uleb128 (insn_ptr, &reg);
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
 	  fs->regs.reg[reg].how = REG_SAVED_EXP;
 	  fs->regs.reg[reg].loc.exp = insn_ptr;
-	  insn_ptr += uoffset;
+	  insn_ptr += ptrtmp;
 	  break;
 
 	  /* From the 2.1 draft.  */
 	case DW_CFA_offset_extended_sf:
-	  insn_ptr = read_uleb128 (insn_ptr, &reg);
-	  insn_ptr = read_sleb128 (insn_ptr, &offset);
-	  offset *= fs->data_align;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
+	  offset = (saddr)ptrtmp * fs->data_align;
 	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
 	  fs->regs.reg[reg].loc.offset = offset;
 	  break;
 	  
 	case DW_CFA_def_cfa_sf:
-	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
-	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_reg = ptrtmp;
+	  insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = (saddr)ptrtmp;
 	  fs->cfa_how = CFA_REG_OFFSET;
 	  break;
 
 	case DW_CFA_def_cfa_offset_sf:
-	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_offset);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  fs->cfa_offset = ptrtmp;
 	  /* cfa_how deliberately not set.  */
 	  break;
 
@@ -852,15 +856,16 @@ execute_cfa_program (const unsigned char *insn_ptr,
 	  break;
 
 	case DW_CFA_GNU_args_size:
-	  insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  context->args_size = ptrtmp;
 	  break;
 
 	case DW_CFA_GNU_negative_offset_extended:
 	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
 	     older PowerPC code.  */
-	  insn_ptr = read_uleb128 (insn_ptr, &reg);
-	  insn_ptr = read_uleb128 (insn_ptr, &uoffset);
-	  offset = (_Unwind_Sword)uoffset * fs->data_align;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
+	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
+	  offset = ptrtmp * fs->data_align;
 	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;
 	  fs->regs.reg[reg].loc.offset = -offset;
 	  break;
@@ -916,7 +921,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
   insn = NULL;
   if (fs->saw_z)
     {
-      _Unwind_Word i;
+      _Unwind_Ptr i;
       aug = read_uleb128 (aug, &i);
       insn = aug + i;
     }
@@ -964,7 +969,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
 	 that this will not be a problem.  */
       {
 	const unsigned char *exp = fs->cfa_exp;
-	_Unwind_Word len;
+	_Unwind_Ptr len;
 
 	exp = read_uleb128 (exp, &len);
 	cfa = (void *) (_Unwind_Ptr)
@@ -992,7 +997,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
       case REG_SAVED_EXP:
 	{
 	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
-	  _Unwind_Word len;
+	  _Unwind_Ptr len;
 	  _Unwind_Ptr val;
 
 	  exp = read_uleb128 (exp, &len);
diff --git a/gcc/unwind.inc b/gcc/unwind.inc
index a1d1a432f63ee764d6704167128f8af85a65757b..85636d40c034b96f56b6345851a530eedcd20c27 100644
--- a/gcc/unwind.inc
+++ b/gcc/unwind.inc
@@ -135,8 +135,8 @@ static _Unwind_Reason_Code
 _Unwind_ForcedUnwind_Phase2(struct _Unwind_Exception *exc,
 			    struct _Unwind_Context *context)
 {
-  _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) exc->private_1;
-  void *stop_argument = (void *) exc->private_2;
+  _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
+  void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
   _Unwind_Reason_Code code, stop_code;
 
   while (1)