diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index e4d0cc43f41..a0798d4468b 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10334,8 +10334,8 @@ return nonzero for any @var{entity} that needs mode-switching.
 If you define this macro, you also have to define
 @code{NUM_MODES_FOR_MODE_SWITCHING}, @code{TARGET_MODE_NEEDED},
 @code{TARGET_MODE_PRIORITY} and @code{TARGET_MODE_EMIT}.
-@code{TARGET_MODE_AFTER}, @code{TARGET_MODE_ENTRY}, and @code{TARGET_MODE_EXIT}
-are optional.
+@code{TARGET_MODE_AFTER}, @code{TARGET_MODE_ENTRY}, @code{TARGET_MODE_EMIT_AFTER},
+and @code{TARGET_MODE_EXIT} are optional.
 @end defmac
 
 @defmac NUM_MODES_FOR_MODE_SWITCHING
@@ -10359,6 +10359,14 @@ to switch from. Sets of a lower numbered entity will be emitted before
 sets of a higher numbered entity to a mode of the same or lower priority.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_MODE_EMIT_AFTER (int @var{entity}, int @var{mode}, int @var{prev_mode}, HARD_REG_SET @var{regs_live})
+Generate one or more insns to set @var{entity} to @var{mode}.
+@var{hard_reg_live} is the set of hard registers live at the point where
+the insn(s) are to be inserted after. @var{prev_moxde} indicates the mode
+to switch from. Sets of a lower numbered entity will be emitted before
+sets of a higher numbered entity to a mode of the same or lower priority.
+@end deftypefn
+
 @deftypefn {Target Hook} int TARGET_MODE_NEEDED (int @var{entity}, rtx_insn *@var{insn})
 @var{entity} is an integer specifying a mode-switched entity.
 If @code{OPTIMIZE_MODE_SWITCHING} is defined, you must define this macro
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 4ac96dc357d..2942ce0be3b 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -6911,8 +6911,8 @@ return nonzero for any @var{entity} that needs mode-switching.
 If you define this macro, you also have to define
 @code{NUM_MODES_FOR_MODE_SWITCHING}, @code{TARGET_MODE_NEEDED},
 @code{TARGET_MODE_PRIORITY} and @code{TARGET_MODE_EMIT}.
-@code{TARGET_MODE_AFTER}, @code{TARGET_MODE_ENTRY}, and @code{TARGET_MODE_EXIT}
-are optional.
+@code{TARGET_MODE_AFTER}, @code{TARGET_MODE_ENTRY}, @code{TARGET_MODE_EMIT_AFTER},
+and @code{TARGET_MODE_EXIT} are optional.
 @end defmac
 
 @defmac NUM_MODES_FOR_MODE_SWITCHING
@@ -6930,6 +6930,8 @@ switch is needed / supplied.
 
 @hook TARGET_MODE_EMIT
 
+@hook TARGET_MODE_EMIT_AFTER
+
 @hook TARGET_MODE_NEEDED
 
 @hook TARGET_MODE_AFTER
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index f483c831c35..98051dff487 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -34,6 +34,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "lcm.h"
 #include "cfgcleanup.h"
 #include "tree-pass.h"
+#include "cfgbuild.h"
+#include "gcse.h"
 
 /* We want target macros for the mode switching code to be able to refer
    to instruction attribute values.  */
@@ -831,6 +833,49 @@ optimize_mode_switching (void)
 			emit_insn_before (mode_set, ptr->insn_ptr);
 		    }
 
+		  if (targetm.mode_switching.emit_after)
+		    {
+		      if (control_flow_insn_p (ptr->insn_ptr)
+			&& ptr->insn_ptr == BB_END (bb))
+			{
+			  edge eg;
+			  edge_iterator eg_iterator;
+
+			  FOR_EACH_EDGE (eg, eg_iterator, bb->succs)
+			    {
+			      start_sequence ();
+			      targetm.mode_switching.emit_after (entity_map[j],
+				ptr->mode, cur_mode, ptr->regs_live);
+			      mode_set = get_insns ();
+			      end_sequence ();
+
+			      if (mode_set != NULL_RTX)
+				{
+				  if (eg->flags & EDGE_ABNORMAL)
+				    insert_insn_end_basic_block (mode_set, bb);
+				  else
+				    insert_insn_on_edge (mode_set, eg);
+
+				  emitted = true;
+				  need_commit = true;
+				}
+			    }
+			}
+		      else
+			{
+			  start_sequence ();
+			  targetm.mode_switching.emit_after (entity_map[j],
+			    ptr->mode, cur_mode, ptr->regs_live);
+			  mode_set = get_insns ();
+			  end_sequence ();
+
+			  if (mode_set != NULL_RTX)
+			    {
+			      emit_insn_after (mode_set, ptr->insn_ptr);
+			      emitted = true;
+			    }
+			}
+		    }
 		  default_rtl_profile ();
 		}
 
diff --git a/gcc/target.def b/gcc/target.def
index a500aeb6714..abcf9dc5c0e 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -7005,6 +7005,15 @@ to switch from. Sets of a lower numbered entity will be emitted before\n\
 sets of a higher numbered entity to a mode of the same or lower priority.",
  void, (int entity, int mode, int prev_mode, HARD_REG_SET regs_live), NULL)
 
+DEFHOOK
+(emit_after,
+ "Generate one or more insns to set @var{entity} to @var{mode}.\n\
+@var{hard_reg_live} is the set of hard registers live at the point where\n\
+the insn(s) are to be inserted after. @var{prev_moxde} indicates the mode\n\
+to switch from. Sets of a lower numbered entity will be emitted before\n\
+sets of a higher numbered entity to a mode of the same or lower priority.",
+ void, (int entity, int mode, int prev_mode, HARD_REG_SET regs_live), NULL)
+
 DEFHOOK
 (needed,
  "@var{entity} is an integer specifying a mode-switched entity.\n\
