diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index efd30ea..6f8285c 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -94,6 +94,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-flow.h"
 #include "cfglayout.h"
 
+static void output_source_line_asm_info (unsigned int, const char *,
+					 int, bool, bool);
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
 static rtx last_var_location_insn;
 
@@ -465,6 +467,7 @@ static void output_call_frame_info (int);
 static void dwarf2out_note_section_used (void);
 static bool clobbers_queued_reg_save (const_rtx);
 static void dwarf2out_frame_debug_expr (rtx, const char *);
+static void dwarf2out_end_prologue (unsigned int, const char*);
 
 /* Support for complex CFA locations.  */
 static void output_cfa_loc (dw_cfi_ref, int);
@@ -4125,6 +4128,21 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
     }
 }
 
+/* Implementation of the gcc_debug_hooks::end_prologue hook.
+
+   If the underlying assembler supports it, emit a .loc asm directive
+   with a 'end_prologue' argument, effectively marking the point where
+   debugger should set a breakpoint when requested to set one on a
+   function.  */
+
+static void
+dwarf2out_end_prologue (unsigned int line, const char *filename)
+{
+  output_source_line_asm_info (line, filename, 0,
+			       /*is_stmt=*/true,
+			       /*is_prologue_end*/true);
+}
+
 /* Output a marker (i.e. a label) for the end of the generated code
    for a function prologue.  This gets called *after* the prologue code has
    been generated.  */
@@ -5767,7 +5785,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
   dwarf2out_vms_end_prologue,
   dwarf2out_vms_begin_epilogue,
 #else
-  debug_nothing_int_charstar,
+  dwarf2out_end_prologue,
   debug_nothing_int_charstar,
 #endif
   dwarf2out_end_epilogue,
@@ -22129,14 +22147,22 @@ dwarf2out_begin_function (tree fun)
 
 /* Output a label to mark the beginning of a source code line entry
    and record information relating to this source line, in
-   'line_info_table' for later output of the .debug_line section.  */
+   'line_info_table' for later output of the .debug_line section.
+
+   If the underlying assembler supports the .loc directive, use it
+   instead of emiting .debug_line state machine operations ourselves.
+
+   The arguments of the functions set their counterpart into the
+   .debug_line state machine registers.
+
+   This is a subroutine of dwarf2out_source_line and and
+   dwarf2out_end_prologue.  */
 
 static void
-dwarf2out_source_line (unsigned int line, const char *filename,
-                       int discriminator, bool is_stmt)
+output_source_line_asm_info (unsigned int line, const char *filename,
+			     int discriminator, bool is_stmt,
+			     bool is_prologue_end)
 {
-  static bool last_is_stmt = true;
-
   if (debug_info_level >= DINFO_LEVEL_NORMAL
       && line != 0)
     {
@@ -22151,19 +22177,42 @@ dwarf2out_source_line (unsigned int line, const char *filename,
 
       if (DWARF2_ASM_LINE_DEBUG_INFO)
 	{
-	  /* Emit the .loc directive understood by GNU as.  */
-	  fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line);
-	  if (is_stmt != last_is_stmt)
+	  static int last_file_num = -1;
+	  static unsigned last_line = 0;
+	  static int last_discriminator = -1;
+	  static bool last_is_stmt = true;
+	  static int last_is_prologue_end = -1;
+
+	  if (last_file_num != file_num
+	      || last_line != line
+	      || last_is_stmt != is_stmt
+	      || last_discriminator != discriminator
+	      || last_is_prologue_end != is_prologue_end)
 	    {
-	      fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0);
-	      last_is_stmt = is_stmt;
-	    }
-	  if (SUPPORTS_DISCRIMINATOR && discriminator != 0)
-	    fprintf (asm_out_file, " discriminator %d", discriminator);
-	  fputc ('\n', asm_out_file);
+	      /* Emit the .loc directive understood by GNU as.  */
+	      fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line);
 
-	  /* Indicate that line number info exists.  */
-	  line_info_table_in_use++;
+	      if (is_stmt != last_is_stmt)
+		{
+		  fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0);
+		  last_is_stmt = is_stmt;
+		}
+
+	      if (is_prologue_end)
+		fprintf (asm_out_file, " prologue_end");
+
+	      if (SUPPORTS_DISCRIMINATOR && discriminator != 0)
+		fprintf (asm_out_file, " discriminator %d", discriminator);
+	      fputc ('\n', asm_out_file);
+
+	      /* Indicate that line number info exists.  */
+	      line_info_table_in_use++;
+
+	      last_file_num = file_num;
+	      last_line = line;
+	      last_discriminator = discriminator;
+	      last_is_prologue_end = is_prologue_end;
+	    }
 	}
       else if (function_section (current_function_decl) != text_section)
 	{
@@ -22245,6 +22294,18 @@ dwarf2out_start_source_file (unsigned int lineno, const char *filename)
     }
 }
 
+/* Output a label to mark the beginning of a source code line entry
+   and record information relating to this source line, in
+   'line_info_table' for later output of the .debug_line section.  */
+
+static void
+dwarf2out_source_line (unsigned int line, const char *filename,
+                       int discriminator, bool is_stmt)
+{
+  output_source_line_asm_info (line, filename, discriminator,
+			       is_stmt, /*is_prolog_end=*/false);
+}
+
 /* Record the end of a source file.  */
 
 static void
