diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index eca000f..bc1bd49 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,32 @@
+2015-06-01  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* completer.c Add arch-utils.h include.
+	(enum reg_completer_targets): New enum.
+	(reg_or_group_completer_1): New function containing old
+	reg_or_group_completer, add and use new parameter to control what
+	is completed on.  Use get_current_arch rather than architecture of
+	currently selected frame.
+	(reg_or_group_completer): Call new reg_or_group_completer_1.
+	(reggroup_completer): Call new reg_or_group_completer_1.
+	* completer.h (reggroup_completer): Add declaration.
+	* tui/tui-regs.c: Add 'completer.h' include.
+	(tui_reg_next_command): Renamed to...
+	(tui_reg_next): ...this.  Adjust parameters and return rather than
+	display new group.
+	(tui_reg_prev_command): Renamed to...
+	(tui_reg_prev): ...this.  Adjust parameters and return rather than
+	display new group.
+	(tui_reg_float_command): Delete.
+	(tui_reg_general_command): Delete.
+	(tui_reg_system_command): Delete.
+	(tui_reg_command): Rewrite to perform switching of register group.
+	Add header comment.
+	(tuireglist): Remove.
+	(tui_reggroup_completer): New function.
+	(_initialize_tui_regs): Remove 'tui reg' sub-commands, update
+	creation of 'tui reg' command.
+	* NEWS: Add comment about 'tui reg' changes.
+
 2015-06-02  Yao Qi  <yao.qi@linaro.org>
 
 	* i386-linux-nat.c: Include linux-nat.h.
diff --git a/gdb/NEWS b/gdb/NEWS
index bbfb55d..2933e35 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -52,6 +52,9 @@
 
 * GDB now supports the vector ABI on S/390 GNU/Linux targets.
 
+* The "tui reg" command now provides completion for all of the
+  available register groups, including target specific groups.
+
 * Guile Scripting
 
   ** Memory ports can now be unbuffered.
diff --git a/gdb/completer.c b/gdb/completer.c
index c8c0e4c..a0be935 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -26,6 +26,7 @@
 #include "target.h"
 #include "reggroups.h"
 #include "user-regs.h"
+#include "arch-utils.h"
 
 #include "cli/cli-decode.h"
 
@@ -969,44 +970,86 @@ signal_completer (struct cmd_list_element *ignore,
   return return_val;
 }
 
-/* Complete on a register or reggroup.  */
+/* Bit-flags for selecting what the register and/or register-group
+   completer should complete on.  */
 
-VEC (char_ptr) *
-reg_or_group_completer (struct cmd_list_element *ignore,
-			const char *text, const char *word)
+enum reg_completer_targets
+  {
+    complete_register_names = 0x1,
+    complete_reggroup_names = 0x2
+  };
+
+/* Complete on a register names (when WITH_REGISTERS is true) and/or
+   reggroup names (when WITH_REGGROUPS) is true.  One, or both of
+   WITH_REGISTERS and WITH_REGGROUPS must be true.  */
+
+static VEC (char_ptr) *
+reg_or_group_completer_1 (struct cmd_list_element *ignore,
+			  const char *text, const char *word,
+			  enum reg_completer_targets targets)
 {
   VEC (char_ptr) *result = NULL;
   size_t len = strlen (word);
   struct gdbarch *gdbarch;
-  struct reggroup *group;
   const char *name;
-  int i;
 
   if (!target_has_registers)
     return result;
 
-  gdbarch = get_frame_arch (get_selected_frame (NULL));
+  gdb_assert ((targets & (complete_register_names
+			  | complete_reggroup_names)) != 0);
+  gdbarch = get_current_arch ();
 
-  for (i = 0;
-       (name = user_reg_map_regnum_to_name (gdbarch, i)) != NULL;
-       i++)
+  if ((targets & complete_register_names) != 0)
     {
-      if (*name != '\0' && strncmp (word, name, len) == 0)
-	VEC_safe_push (char_ptr, result, xstrdup (name));
+      int i;
+
+      for (i = 0;
+	   (name = user_reg_map_regnum_to_name (gdbarch, i)) != NULL;
+	   i++)
+	{
+	  if (*name != '\0' && strncmp (word, name, len) == 0)
+	    VEC_safe_push (char_ptr, result, xstrdup (name));
+	}
     }
 
-  for (group = reggroup_next (gdbarch, NULL);
-       group != NULL;
-       group = reggroup_next (gdbarch, group))
+  if ((targets & complete_reggroup_names) != 0)
     {
-      name = reggroup_name (group);
-      if (strncmp (word, name, len) == 0)
-	VEC_safe_push (char_ptr, result, xstrdup (name));
+      struct reggroup *group;
+
+      for (group = reggroup_next (gdbarch, NULL);
+	   group != NULL;
+	   group = reggroup_next (gdbarch, group))
+	{
+	  name = reggroup_name (group);
+	  if (strncmp (word, name, len) == 0)
+	    VEC_safe_push (char_ptr, result, xstrdup (name));
+	}
     }
 
   return result;
 }
 
+/* Perform completion on register and reggroup names.  */
+
+VEC (char_ptr) *
+reg_or_group_completer (struct cmd_list_element *ignore,
+			const char *text, const char *word)
+{
+  return reg_or_group_completer_1 (ignore, text, word,
+				   (complete_register_names
+				    | complete_reggroup_names));
+}
+
+/* Perform completion on reggroup names.  */
+
+VEC (char_ptr) *
+reggroup_completer (struct cmd_list_element *ignore,
+		    const char *text, const char *word)
+{
+  return reg_or_group_completer_1 (ignore, text, word,
+				   complete_reggroup_names);
+}
 
 /* Get the list of chars that are considered as word breaks
    for the current command.  */
diff --git a/gdb/completer.h b/gdb/completer.h
index 56e1a2b..6c1f257 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -96,6 +96,9 @@ extern VEC (char_ptr) *signal_completer (struct cmd_list_element *,
 extern VEC (char_ptr) *reg_or_group_completer (struct cmd_list_element *,
 					       const char *, const char *);
 
+extern VEC (char_ptr) *reggroup_completer (struct cmd_list_element *,
+					   const char *, const char *);
+
 extern char *get_gdb_completer_quote_characters (void);
 
 extern char *gdb_completion_word_break_characters (void);
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 171d30e..24555c2 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-01  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gdb.texinfo (TUI Commands): Bring all 'tui reg' commands into a
+	single table entry.
+
 2015-05-27  Doug Evans  <dje@google.com>
 
 	* gdb.texinfo (Debugging Output): Mention set/show debug dwarf-line.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 9ea846a..f927eff 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -25009,27 +25009,34 @@ Make the command window active for scrolling.
 @kindex refresh
 Refresh the screen.  This is similar to typing @kbd{C-L}.
 
-@item tui reg float
+@item tui reg @var{group}
 @kindex tui reg
-Show the floating point registers in the register window.
-
-@item tui reg general
-Show the general registers in the register window.
-
-@item tui reg next
-Show the next register group.  The list of register groups as well as
-their order is target specific.  The predefined register groups are the
-following: @code{general}, @code{float}, @code{system}, @code{vector},
-@code{all}, @code{save}, @code{restore}.
-
-@item tui reg prev
-Show the previous register group.  The list of register groups as well
-as their order is target specific.  The predefined register groups are
-the following: @code{general}, @code{float}, @code{system},
-@code{vector}, @code{all}, @code{save}, @code{restore}.
-
-@item tui reg system
-Show the system registers in the register window.
+Changes the register group displayed in the tui register window to
+@var{group}.  If the register window is not currently displayed this
+command will cause the register window to be displayed.  The list of
+register groups, as well as their order is target specific. The
+following groups are avaiable on most targets:
+@table @code
+@item next
+Repeatedly selecting this group will cause the display to cycle
+through all of the available register groups.
+
+@item prev
+Repeatedly selecting this group will cause the display to cycle
+through all of the available register groups in the reverse order to
+@var{next}.
+
+@item general
+Display the general registers.
+@item float
+Display the floating point registers.
+@item system
+Display the system registers.
+@item vector
+Display the vector registers.
+@item all
+Display all registers.
+@end table
 
 @item update
 @kindex update
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 6ac3c2b..a61fadb 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -39,6 +39,7 @@
 #include "tui/tui-io.h"
 #include "reggroups.h"
 #include "valprint.h"
+#include "completer.h"
 
 #include "gdb_curses.h"
 
@@ -556,74 +557,135 @@ tui_display_register (struct tui_data_element *data,
     }
 }
 
-static void
-tui_reg_next_command (char *arg, int from_tty)
+/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
+   around behaviour.  Returns the next register group, or NULL if the
+   register window is not currently being displayed.  */
+
+static struct reggroup *
+tui_reg_next (struct gdbarch *gdbarch)
 {
-  struct gdbarch *gdbarch = get_current_arch ();
+  struct reggroup *group = NULL;
 
   if (TUI_DATA_WIN != NULL)
     {
-      struct reggroup *group
-        = TUI_DATA_WIN->detail.data_display_info.current_group;
-
+      group = TUI_DATA_WIN->detail.data_display_info.current_group;
       group = reggroup_next (gdbarch, group);
       if (group == NULL)
         group = reggroup_next (gdbarch, NULL);
-
-      if (group != NULL)
-        tui_show_registers (group);
     }
+  return group;
 }
 
-/* Implementation of the "tui reg prev" command.  Cycle the register group
-   displayed in the tui REG window, moving backwards through the list of
-   available register groups.  */
+/* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
+   around behaviour.  Returns the previous register group, or NULL if the
+   register window is not currently being displayed.  */
 
-static void
-tui_reg_prev_command (char *arg, int from_tty)
+static struct reggroup *
+tui_reg_prev (struct gdbarch *gdbarch)
 {
-  struct gdbarch *gdbarch = get_current_arch ();
+  struct reggroup *group = NULL;
 
   if (TUI_DATA_WIN != NULL)
     {
-      struct reggroup *group
-        = TUI_DATA_WIN->detail.data_display_info.current_group;
-
+      group = TUI_DATA_WIN->detail.data_display_info.current_group;
       group = reggroup_prev (gdbarch, group);
       if (group == NULL)
 	group = reggroup_prev (gdbarch, NULL);
-
-      if (group != NULL)
-	tui_show_registers (group);
     }
+  return group;
 }
 
-static void
-tui_reg_float_command (char *arg, int from_tty)
-{
-  tui_show_registers (float_reggroup);
-}
+/* Implement the 'tui reg' command.  Changes the register group displayed
+   in the tui register window.  Displays the tui register window if it is
+   not already on display.  */
 
 static void
-tui_reg_general_command (char *arg, int from_tty)
+tui_reg_command (char *args, int from_tty)
 {
-  tui_show_registers (general_reggroup);
-}
+  struct gdbarch *gdbarch = get_current_arch ();
 
-static void
-tui_reg_system_command (char *arg, int from_tty)
-{
-  tui_show_registers (system_reggroup);
+  if (args != NULL)
+    {
+      struct reggroup *group, *match = NULL;
+      size_t len = strlen (args);
+
+      /* Make sure the curses mode is enabled.  */
+      tui_enable ();
+
+      /* Make sure the register window is visible.  If not, select an
+	 appropriate layout.  We need to do this before trying to run the
+	 'next' or 'prev' commands.  */
+      if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
+	tui_set_layout_by_name (DATA_NAME);
+
+      if (strncmp (args, "next", len) == 0)
+	match = tui_reg_next (gdbarch);
+      else if (strncmp (args, "prev", len) == 0)
+	match = tui_reg_prev (gdbarch);
+
+      /* This loop matches on the initial part of a register group
+	 name.  If this initial part in ARGS matches only one register
+	 group then the switch is made.  */
+      for (group = reggroup_next (gdbarch, NULL);
+	   group != NULL;
+	   group = reggroup_next (gdbarch, group))
+	{
+	  if (strncmp (reggroup_name (group), args, len) == 0)
+	    {
+	      if (match != NULL)
+		error (_("ambiguous register group name '%s'"), args);
+	      match = group;
+	    }
+	}
+
+      if (match == NULL)
+	error (_("unknown register group '%s'"), args);
+
+      tui_show_registers (match);
+    }
+  else
+    {
+      struct reggroup *group;
+      int first;
+
+      printf_unfiltered (_("\"tui reg\" must be followed by the name of "
+			   "either a register group,\nor one of 'next' "
+			   "or 'prev'.  Known register groups are:\n"));
+
+      for (first = 1, group = reggroup_next (gdbarch, NULL);
+	   group != NULL;
+	   first = 0, group = reggroup_next (gdbarch, group))
+	{
+	  if (!first)
+	    printf_unfiltered (", ");
+	  printf_unfiltered ("%s", reggroup_name (group));
+	}
+
+      printf_unfiltered ("\n");
+    }
 }
 
-static struct cmd_list_element *tuireglist;
+/* Complete names of register groups, and add the special "prev" and "next"
+   names.  */
 
-static void
-tui_reg_command (char *args, int from_tty)
+static VEC (char_ptr) *
+tui_reggroup_completer (struct cmd_list_element *ignore,
+			const char *text, const char *word)
 {
-  printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
-                     "tui reg command.\n"));
-  help_list (tuireglist, "tui reg ", all_commands, gdb_stdout);
+  VEC (char_ptr) *result = NULL;
+  static const char *extra[] = { "next", "prev", NULL };
+  size_t len = strlen (word);
+  const char **tmp;
+
+  result = reggroup_completer (ignore, text, word);
+
+  for (tmp = extra; *tmp != NULL; ++tmp)
+    {
+      if (strncmp (word, *tmp, len) == 0)
+	VEC_safe_push (char_ptr, result, xstrdup (*tmp));
+    }
+
+  return result;
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
@@ -632,30 +694,13 @@ extern initialize_file_ftype _initialize_tui_regs;
 void
 _initialize_tui_regs (void)
 {
-  struct cmd_list_element **tuicmd;
+  struct cmd_list_element **tuicmd, *cmd;
 
   tuicmd = tui_get_cmd_list ();
 
-  add_prefix_cmd ("reg", class_tui, tui_reg_command,
-                  _("TUI commands to control the register window."),
-                  &tuireglist, "tui reg ", 0,
-                  tuicmd);
-
-  add_cmd ("float", class_tui, tui_reg_float_command,
-           _("Display only floating point registers."),
-           &tuireglist);
-  add_cmd ("general", class_tui, tui_reg_general_command,
-           _("Display only general registers."),
-           &tuireglist);
-  add_cmd ("system", class_tui, tui_reg_system_command,
-           _("Display only system registers."),
-           &tuireglist);
-  add_cmd ("next", class_tui, tui_reg_next_command,
-           _("Display next register group."),
-           &tuireglist);
-  add_cmd ("prev", class_tui, tui_reg_prev_command,
-           _("Display previous register group."),
-           &tuireglist);
+  cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
+TUI command to control the register window."), tuicmd);
+  set_cmd_completer (cmd, tui_reggroup_completer);
 }
 
 
