diff --git a/gcc/calls.c b/gcc/calls.c
index e798c7a..edee262 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3191,6 +3191,27 @@ expand_call (tree exp, rtx target, int ignore)
 	  add_reg_note (last, REG_CALL_DECL, datum);
 	}
 
+      if (targetm.call_clobbered_regs != NULL)
+	{
+	  struct hard_reg_set_container call_clobbered_regs;
+	  rtx last = last_call_insn ();
+
+	  CLEAR_HARD_REG_SET (call_clobbered_regs.set);
+	  if (targetm.call_clobbered_regs (fndecl, &call_clobbered_regs))
+	    {
+	      hard_reg_set_iterator hrsi;
+	      unsigned int i;
+	      EXECUTE_IF_SET_IN_HARD_REG_SET (call_clobbered_regs.set, 0, i, hrsi)
+		{
+		  rtx reg = gen_rtx_REG (word_mode, i);
+		  CALL_INSN_FUNCTION_USAGE (last)
+		    = gen_rtx_EXPR_LIST (VOIDmode,
+					 gen_rtx_CLOBBER (VOIDmode, reg),
+					 CALL_INSN_FUNCTION_USAGE (last));
+		}
+	    }
+	}
+
       /* If the call setup or the call itself overlaps with anything
 	 of the argument setup we probably clobbered our call address.
 	 In that case we can't do sibcalls.  */
@@ -4226,6 +4247,27 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
       add_reg_note (last, REG_CALL_DECL, datum);
     }
 
+  if (targetm.call_clobbered_regs != NULL)
+    {
+      struct hard_reg_set_container call_clobbered_regs;
+      rtx last = last_call_insn ();
+
+      CLEAR_HARD_REG_SET (call_clobbered_regs.set);
+      if (targetm.call_clobbered_regs (fndecl, &call_clobbered_regs))
+	{
+	  hard_reg_set_iterator hrsi;
+	  unsigned int i;
+	  EXECUTE_IF_SET_IN_HARD_REG_SET (call_clobbered_regs.set, 0, i, hrsi)
+	    {
+	      rtx reg = gen_rtx_REG (word_mode, i);
+	      CALL_INSN_FUNCTION_USAGE (last)
+		= gen_rtx_EXPR_LIST (VOIDmode,
+				     gen_rtx_CLOBBER (VOIDmode, reg),
+				     CALL_INSN_FUNCTION_USAGE (last));
+	    }
+	}
+    }
+
   /* Right-shift returned value if necessary.  */
   if (!pcc_struct_value
       && TYPE_MODE (tfom) != BLKmode
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b8ca17e..cd52f73 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3091,6 +3091,7 @@ This describes the stack layout and calling conventions.
 * Profiling::
 * Tail Calls::
 * Stack Smashing Protection::
+* Miscellaneous Register Hooks::
 @end menu
 
 @node Frame Layout
@@ -5016,6 +5017,14 @@ normally defined in @file{libgcc2.c}.
 Whether this target supports splitting the stack when the options described in @var{opts} have been passed.  This is called after options have been parsed, so the target may reject splitting the stack in some configurations.  The default version of this hook returns false.  If @var{report} is true, this function may issue a warning or error; if @var{report} is false, it must simply return a value
 @end deftypefn
 
+@node Miscellaneous Register Hooks
+@subsection Miscellaneous register hooks
+@cindex miscellaneous register hooks
+
+@deftypefn {Target Hook} bool TARGET_CALL_CLOBBERED_REGS (tree @var{fndecl}, struct hard_reg_set_container *@var{regs})
+Add any hard registers to @var{regs} that are set or clobbered by a call @var{fndecl} which are not present in the rtl representation.  This includes f.i. registers reserved for PLT, or tmp registers set or clobbered by the call, but not registers set or clobbered by the called function.  This hook returns true if it added any registers to @var{regs}.  Not defining this hook will result in conservative assumptions.
+@end deftypefn
+
 @node Varargs
 @section Implementing the Varargs Macros
 @cindex varargs implementation
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index d793d26..7022d7c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2720,6 +2720,7 @@ This describes the stack layout and calling conventions.
 * Profiling::
 * Tail Calls::
 * Stack Smashing Protection::
+* Miscellaneous Register Hooks::
 @end menu
 
 @node Frame Layout
@@ -3985,6 +3986,12 @@ the function prologue.  Normally, the profiling code comes after.
 
 @hook TARGET_SUPPORTS_SPLIT_STACK
 
+@node Miscellaneous Register Hooks
+@subsection Miscellaneous register hooks
+@cindex miscellaneous register hooks
+
+@hook TARGET_CALL_CLOBBERED_REGS
+
 @node Varargs
 @section Implementing the Varargs Macros
 @cindex varargs implementation
diff --git a/gcc/target.def b/gcc/target.def
index 3a64cd1..b7bb40c 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5130,6 +5130,17 @@ FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM.",
  void, (bitmap regs),
  hook_void_bitmap)
 
+DEFHOOK
+(call_clobbered_regs,
+ "Add any hard registers to @var{regs} that are set or clobbered by a call\
+ @var{fndecl} which are not present in the rtl representation.  This includes\
+ f.i. registers reserved for PLT, or tmp registers set or clobbered by the\
+ call, but not registers set or clobbered by the called function.  This hook\
+ returns true if it added any registers to @var{regs}.  Not defining this hook\
+ will result in conservative assumptions.",
+ bool, (tree fndecl, struct hard_reg_set_container *regs),
+ NULL)
+
 /* Fill in additional registers set up by prologue into a regset.  */
 DEFHOOK
 (set_up_by_prologue,
-- 
1.8.3.2

