diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 2782535..0c1a0ab 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -117,12 +117,12 @@ static const char *const core_v2_register_names[] = {
   "r44", "r45", "r46", "r47",
   "r48", "r49", "r50", "r51",
   "r52", "r53", "r54", "r55",
-  "r56", "r57", "accl", "acch",
+  "r56", "r57", "r58", "r59",
   "lp_count", "reserved", "limm", "pcl",
 };
 
 static const char *const aux_minimal_register_names[] = {
-  "pc", "status32",
+  "pc", "status32", "lp_start", "lp_end", "bta"
 };
 
 static const char *const core_arcompact_register_names[] = {
@@ -1761,7 +1761,7 @@ static const struct frame_base arc_normal_base = {
 
 static int
 arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
-		struct tdesc_arch_data **tdesc_data)
+		struct tdesc_arch_data **tdesc_data, struct gdbarch_tdep *tdep)
 {
   if (arc_debug)
     debug_printf ("arc: Target description initialization.\n");
@@ -1892,17 +1892,44 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
 			    || (i >= ARC_R16_REGNUM && i <= ARC_R25_REGNUM)))
 	continue;
 
-      valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i,
+      /* R58 and R59 can have special names: ACCL and ACCH, however which
+	 one is which depends on target endianness - for little endian R58
+	 is ACCL, R59 is ACCH; vice versa for big endian.  */
+
+      const char *const r58_names[] = {
+	core_regs[58],
+	(info.byte_order == BFD_ENDIAN_LITTLE ? "accl" : "acch"),
+	NULL
+      };
+      const char *const r59_names[] = {
+	core_regs[59],
+	(info.byte_order == BFD_ENDIAN_LITTLE ? "acch" : "accl"),
+	NULL
+      };
+
+      switch (i)
+	{
+	case ARC_R58_REGNUM:
+	  valid_p = tdesc_numbered_register_choices (feature, tdesc_data_loc,
+						     i, r58_names);
+	  break;
+	case ARC_R59_REGNUM:
+	  valid_p = tdesc_numbered_register_choices (feature, tdesc_data_loc,
+						     i, r59_names);
+	  break;
+	default:
+	  valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i,
 					 core_regs[i]);
+	}
 
       /* - Ignore errors in extension registers - they are optional.
 	 - Ignore missing ILINK because it doesn't make sense for Linux.
-	 - Ignore missing ILINK2 when architecture is ARCompact, because it
-	 doesn't make sense for Linux targets.
+	 - Ignore missing ILINK2 when architecture is ARCompact, because
+	 it doesn't make sense for Linux targets.
 
-	 In theory those optional registers should be in separate features, but
-	 that would create numerous but tiny features, which looks like an
-	 overengineering of a rather simple task.  */
+	 In theory those optional registers should be in separate
+	 features, but that would create numerous but tiny features, which
+	 looks like an overengineering of a rather simple task.  */
       if (!valid_p && (i <= ARC_SP_REGNUM || i == ARC_BLINK_REGNUM
 		       || i == ARC_LP_COUNT_REGNUM || i == ARC_PCL_REGNUM
 		       || (i == ARC_R30_REGNUM && is_arcv2)))
@@ -1929,7 +1956,9 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
     {
       const char *name = aux_minimal_register_names[i - ARC_FIRST_AUX_REGNUM];
       valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i, name);
-      if (!valid_p)
+
+      /* Only STATUS32 and PC are mandatory.  */
+      if (!valid_p && (i == ARC_PC_REGNUM || i == ARC_STATUS32_REGNUM))
 	{
 	  arc_print (_("Error: Cannot find required register `%s' "
 		       "in feature `%s'.\n"),
@@ -1937,6 +1966,11 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
 	  tdesc_data_cleanup (tdesc_data_loc);
 	  return FALSE;
 	}
+      /* Hardware loops present if both its registers are.  */
+      else if (ARC_LP_START_REGNUM == i)
+	tdep->has_hw_loops = valid_p;
+      else if (ARC_LP_END_REGNUM == i)
+	tdep->has_hw_loops &= valid_p;
     }
 
   *tdesc = tdesc_loc;
@@ -1956,13 +1990,17 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (arc_debug)
     debug_printf ("arc: Architecture initialization.\n");
 
-  if (!arc_tdesc_init (info, &tdesc, &tdesc_data))
-    return NULL;
-
   /* Allocate the ARC-private target-dependent information structure, and the
      GDB target-independent information structure.  */
   struct gdbarch_tdep *tdep = XCNEW (struct gdbarch_tdep);
   tdep->jb_pc = -1; /* No longjmp support by default.  */
+
+  if (!arc_tdesc_init (info, &tdesc, &tdesc_data, tdep))
+    {
+      XDELETE (tdep);
+      return NULL;
+    }
+
   struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
 
   /* Data types.  */
@@ -1993,6 +2031,13 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_ps_regnum (gdbarch, ARC_STATUS32_REGNUM);
   set_gdbarch_fp0_regnum (gdbarch, -1);	/* No FPU registers.  */
 
+  /* Confirm that register name lists have proper length.  */
+  gdb_static_assert (ARC_LAST_REGNUM + 1
+		     == (ARRAY_SIZE (core_v2_register_names)
+			 + ARRAY_SIZE (aux_minimal_register_names)));
+  gdb_static_assert (ARRAY_SIZE (core_v2_register_names)
+		     == ARRAY_SIZE (core_arcompact_register_names));
+
   set_gdbarch_dummy_id (gdbarch, arc_dummy_id);
   set_gdbarch_push_dummy_call (gdbarch, arc_push_dummy_call);
   set_gdbarch_push_dummy_code (gdbarch, arc_push_dummy_code);
diff --git a/gdb/arc-tdep.h b/gdb/arc-tdep.h
index 580ccb7..12177f0 100644
--- a/gdb/arc-tdep.h
+++ b/gdb/arc-tdep.h
@@ -53,6 +53,8 @@ enum arc_regnum
     ARC_R30_REGNUM,
     /* Return address from function.  */
     ARC_BLINK_REGNUM,
+    ARC_R58_REGNUM = 58,
+    ARC_R59_REGNUM,
     /* Zero-delay loop counter.  */
     ARC_LP_COUNT_REGNUM = 60,
     /* Reserved register number.  There should never be a register with such
@@ -68,14 +70,21 @@ enum arc_regnum
     /* Program counter, aligned to 4-bytes, read-only.  */
     ARC_PCL_REGNUM,
     ARC_LAST_CORE_REGNUM = ARC_PCL_REGNUM,
+
     /* AUX registers.  */
     /* Actual program counter.  */
     ARC_PC_REGNUM,
     ARC_FIRST_AUX_REGNUM = ARC_PC_REGNUM,
     /* Status register.  */
     ARC_STATUS32_REGNUM,
-    ARC_LAST_REGNUM = ARC_STATUS32_REGNUM,
-    ARC_LAST_AUX_REGNUM = ARC_STATUS32_REGNUM,
+    /* Zero-delay loop start instruction.  */
+    ARC_LP_START_REGNUM,
+    /* Zero-delay loop next-after-last instruction.  */
+    ARC_LP_END_REGNUM,
+    /* Branch target address.  */
+    ARC_BTA_REGNUM,
+    ARC_LAST_AUX_REGNUM = ARC_BTA_REGNUM,
+    ARC_LAST_REGNUM = ARC_LAST_AUX_REGNUM,
 
     /* Additional ABI constants.  */
     ARC_FIRST_ARG_REGNUM = ARC_R0_REGNUM,
@@ -100,6 +109,9 @@ struct gdbarch_tdep
   /* Offset to PC value in jump buffer.  If this is negative, longjmp
      support will be disabled.  */
   int jb_pc;
+
+  /* Whether target has hardware (aka zero-delay) loops.  */
+  bool has_hw_loops;
 };
 
 /* Utility functions used by other ARC-specific modules.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index bfeb7a9..69a4a70 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -41614,7 +41614,8 @@ difference with @samp{org.gnu.gdb.arc.core.v2} feature is in the names of
 ARC v2, but @samp{ilink2} is optional on ARCompact.
 
 The @samp{org.gnu.gdb.arc.aux-minimal} feature is required for all ARC
-targets.  It should contain registers @samp{pc} and @samp{status32}.
+targets.  It should contain registers @samp{pc} and @samp{status32}.  It may
+contain registers @samp{lp_start}, @samp{lp_end} and @samp{bta}.
 
 @node ARM Features
 @subsection ARM Features
