Index: gcc/doc/options.texi
===================================================================
--- gcc/doc/options.texi	(revision 166309)
+++ gcc/doc/options.texi	(working copy)
@@ -162,6 +162,10 @@ generic error message is used.  @var{mes
 @samp{%qs} format, which will be used to format the name of the option
 passed.
 
+@item Args(@var{n})
+For an option marked @code{Separate}, indicate that it takes @var{n}
+arguments.  The default is 1.
+
 @item UInteger
 The option's argument is a non-negative integer.  The option parser
 will check and convert the argument before passing it to the relevant
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 166309)
+++ gcc/doc/tm.texi	(working copy)
@@ -99,21 +99,6 @@ from being defined in the @file{.h} file
 @c prevent bad page break with this line
 You can control the compilation driver.
 
-@defmac WORD_SWITCH_TAKES_ARG (@var{name})
-A C expression which determines whether the option @option{-@var{name}}
-takes arguments.  The value should be the number of arguments that
-option takes--zero, for many options.
-This macro does not need to handle options defined in @file{.opt}
-files, only those that are handled purely through specs.
-
-By default, this macro is defined as
-@code{DEFAULT_WORD_SWITCH_TAKES_ARG}, which handles the standard options
-properly.  You need not define @code{WORD_SWITCH_TAKES_ARG} unless you
-wish to add additional options which take arguments.  Any redefinition
-should call @code{DEFAULT_WORD_SWITCH_TAKES_ARG} and then check for
-additional options.
-@end defmac
-
 @defmac TARGET_OPTION_TRANSLATE_TABLE
 If defined, a list of pairs of strings, the first of which is a
 potential command line target to the @file{gcc} driver program, and the
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 166309)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -99,21 +99,6 @@ from being defined in the @file{.h} file
 @c prevent bad page break with this line
 You can control the compilation driver.
 
-@defmac WORD_SWITCH_TAKES_ARG (@var{name})
-A C expression which determines whether the option @option{-@var{name}}
-takes arguments.  The value should be the number of arguments that
-option takes--zero, for many options.
-This macro does not need to handle options defined in @file{.opt}
-files, only those that are handled purely through specs.
-
-By default, this macro is defined as
-@code{DEFAULT_WORD_SWITCH_TAKES_ARG}, which handles the standard options
-properly.  You need not define @code{WORD_SWITCH_TAKES_ARG} unless you
-wish to add additional options which take arguments.  Any redefinition
-should call @code{DEFAULT_WORD_SWITCH_TAKES_ARG} and then check for
-additional options.
-@end defmac
-
 @defmac TARGET_OPTION_TRANSLATE_TABLE
 If defined, a list of pairs of strings, the first of which is a
 potential command line target to the @file{gcc} driver program, and the
Index: gcc/opts-common.c
===================================================================
--- gcc/opts-common.c	(revision 166309)
+++ gcc/opts-common.c	(working copy)
@@ -24,8 +24,7 @@ along with GCC; see the file COPYING3.  
 #include "opts.h"
 #include "flags.h"
 #include "diagnostic.h"
-#include "tm.h" /* For WORD_SWITCH_TAKES_ARG and
-		   TARGET_OPTION_TRANSLATE_TABLE.  */
+#include "tm.h" /* For TARGET_OPTION_TRANSLATE_TABLE.  */
 
 static void prune_options (struct cl_decoded_option **, unsigned int *);
 
@@ -288,7 +287,7 @@ decode_cmdline_option (const char **argv
   size_t opt_index;
   const char *arg = 0;
   int value = 1;
-  unsigned int result = 1, i, extra_args;
+  unsigned int result = 1, i, extra_args, separate_args;
   int adjust_len = 0;
   size_t total_len;
   char *p;
@@ -366,10 +365,15 @@ decode_cmdline_option (const char **argv
     errors |= CL_ERR_DISABLED;
 
   /* Determine whether there may be a separate argument based on
-     whether this option is being processed for the driver.  */
+     whether this option is being processed for the driver, and, if
+     so, how many such arguments.  */
   separate_arg_flag = ((option->flags & CL_SEPARATE)
 		       && !((option->flags & CL_NO_DRIVER_ARG)
 			    && (lang_mask & CL_DRIVER)));
+  separate_args = (separate_arg_flag
+		   ? ((option->flags & CL_SEPARATE_NARGS_MASK)
+		      >> CL_SEPARATE_NARGS_SHIFT) + 1
+		   : 0);
   joined_arg_flag = (option->flags & CL_JOINED) != 0;
 
   /* Sort out any argument the switch takes.  */
@@ -399,10 +403,14 @@ decode_cmdline_option (const char **argv
   else if (separate_arg_flag)
     {
       arg = argv[extra_args + 1];
-      result = extra_args + 2;
-      if (arg == NULL)
-	result = extra_args + 1;
-      else
+      for (i = 0; i < separate_args; i++)
+	if (argv[extra_args + 1 + i] == NULL)
+	  {
+	    errors |= CL_ERR_MISSING_ARG;
+	    break;
+	  }
+      result = extra_args + 1 + i;
+      if (arg != NULL)
 	have_separate_arg = true;
     }
 
@@ -461,6 +469,11 @@ decode_cmdline_option (const char **argv
 				    && (lang_mask & CL_DRIVER)));
 	  joined_arg_flag = (option->flags & CL_JOINED) != 0;
 
+	  if (separate_args > 1 || (option->flags & CL_SEPARATE_NARGS_MASK))
+	    gcc_assert (separate_args
+			== ((option->flags & CL_SEPARATE_NARGS_MASK)
+			    >> CL_SEPARATE_NARGS_SHIFT) + 1);
+
 	  if (!(errors & CL_ERR_MISSING_ARG))
 	    {
 	      if (separate_arg_flag || joined_arg_flag)
@@ -504,22 +517,7 @@ decode_cmdline_option (const char **argv
   decoded->warn_message = warn_message;
 
   if (opt_index == OPT_SPECIAL_unknown)
-    {
-      /* Skip the correct number of arguments for options handled
-	 through specs.  */
-      const char *popt ATTRIBUTE_UNUSED = argv[0] + 1;
-
-      gcc_assert (result == 1);
-      if (WORD_SWITCH_TAKES_ARG (popt))
-	result += WORD_SWITCH_TAKES_ARG (popt);
-      if (result > 1)
-	for (i = 1; i < result; i++)
-	  if (argv[i] == NULL)
-	    {
-	      result = i;
-	      break;
-	    }
-    }
+    gcc_assert (result == 1);
 
   gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option));
   decoded->canonical_option_num_elements = result;
@@ -538,7 +536,21 @@ decode_cmdline_option (const char **argv
 	decoded->canonical_option[i] = NULL;
     }
   if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore)
-    generate_canonical_option (opt_index, arg, value, decoded);
+    {
+      generate_canonical_option (opt_index, arg, value, decoded);
+      if (separate_args > 1)
+	{
+	  for (i = 0; i < separate_args; i++)
+	    {
+	      if (argv[extra_args + 1 + i] == NULL)
+		  break;
+	      else
+		decoded->canonical_option[1 + i] = argv[extra_args + 1 + i];
+	    }
+	  gcc_assert (result == 1 + i);
+	  decoded->canonical_option_num_elements = result;
+	}
+    }
   decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len);
   for (i = 0; i < result; i++)
     {
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	(revision 166309)
+++ gcc/defaults.h	(working copy)
@@ -32,14 +32,6 @@ see the files COPYING3 and COPYING.RUNTI
 #define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0)
 #endif
 
-/* This defines which multi-letter switches take arguments.  */
-
-#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR)		0
-
-#ifndef WORD_SWITCH_TAKES_ARG
-#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
-#endif
-
 /* Store in OUTPUT a string (made with alloca) containing an
    assembler-name for a local static variable or function named NAME.
    LABELNO is an integer which is different for each call.  */
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 166309)
+++ gcc/opts.h	(working copy)
@@ -71,12 +71,12 @@ extern const unsigned int cl_options_cou
 extern const char *const lang_names[];
 extern const unsigned int cl_lang_count;
 
-#define CL_PARAMS               (1 << 13) /* Fake entry.  Used to display --param info with --help.  */
-#define CL_WARNING		(1 << 14) /* Enables an (optional) warning message.  */
-#define CL_OPTIMIZATION		(1 << 15) /* Enables an (optional) optimization.  */
-#define CL_DRIVER		(1 << 16) /* Driver option.  */
-#define CL_TARGET		(1 << 17) /* Target-specific option.  */
-#define CL_COMMON		(1 << 18) /* Language-independent.  */
+#define CL_PARAMS               (1 << 11) /* Fake entry.  Used to display --param info with --help.  */
+#define CL_WARNING		(1 << 12) /* Enables an (optional) warning message.  */
+#define CL_OPTIMIZATION		(1 << 13) /* Enables an (optional) optimization.  */
+#define CL_DRIVER		(1 << 14) /* Driver option.  */
+#define CL_TARGET		(1 << 15) /* Target-specific option.  */
+#define CL_COMMON		(1 << 16) /* Language-independent.  */
 
 #define CL_MIN_OPTION_CLASS	CL_PARAMS
 #define CL_MAX_OPTION_CLASS	CL_COMMON
@@ -86,6 +86,11 @@ extern const unsigned int cl_lang_count;
    This distinction is important because --help will not list options
    which only have these higher bits set.  */
 
+/* Options marked with CL_SEPARATE take a number of separate arguments
+   (1 to 4) that is one more than the number in this bit-field.  */
+#define CL_SEPARATE_NARGS_SHIFT	17
+#define CL_SEPARATE_NARGS_MASK	(3 << CL_SEPARATE_NARGS_SHIFT)
+
 #define CL_SEPARATE_ALIAS	(1 << 19) /* Option is an alias when used with separate argument.  */
 #define CL_NO_DRIVER_ARG	(1 << 20) /* Option takes no argument in the driver.  */
 #define CL_REJECT_DRIVER	(1 << 21) /* Reject this option in the driver.  */
Index: gcc/system.h
===================================================================
--- gcc/system.h	(revision 166309)
+++ gcc/system.h	(working copy)
@@ -776,7 +776,7 @@ extern void fancy_abort (const char *, i
 	STACK_CHECK_PROBE_INTERVAL STACK_CHECK_PROBE_LOAD		   \
 	ORDER_REGS_FOR_LOCAL_ALLOC FUNCTION_OUTGOING_VALUE		   \
 	ASM_DECLARE_CONSTANT_NAME MODIFY_TARGET_NAME SWITCHES_NEED_SPACES  \
-	SWITCH_CURTAILS_COMPILATION SWITCH_TAKES_ARG
+	SWITCH_CURTAILS_COMPILATION SWITCH_TAKES_ARG WORD_SWITCH_TAKES_ARG
 
 /* Hooks that are no longer used.  */
  #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE	\
Index: gcc/opt-functions.awk
===================================================================
--- gcc/opt-functions.awk	(revision 166309)
+++ gcc/opt-functions.awk	(working copy)
@@ -100,6 +100,12 @@ function switch_flags (flags)
 	  test_flag("Warning", flags,  " | CL_WARNING") \
 	  test_flag("Optimization", flags,  " | CL_OPTIMIZATION") \
 	  test_flag("Report", flags, " | CL_REPORT")
+	sep_args = opt_args("Args", flags)
+	if (sep_args != "") {
+		sep_args--
+		result = result " | (" sep_args \
+		    " << CL_SEPARATE_NARGS_SHIFT)"
+	}
 	sub( "^0 \\| ", "", result )
 	return result
 }
Index: gcc/config/darwin.opt
===================================================================
--- gcc/config/darwin.opt	(revision 166309)
+++ gcc/config/darwin.opt	(working copy)
@@ -96,6 +96,9 @@ Driver Separate
 Zseg_addr_table
 Driver Separate
 
+Zsegaddr
+Driver Separate Args(2)
+
 Zsegs_read_only_addr
 Driver Separate
 
@@ -129,9 +132,27 @@ Driver Separate
 read_only_relocs
 Driver Separate
 
+sectalign
+Driver Separate Args(3)
+
+sectcreate
+Driver Separate Args(3)
+
+sectobjectsymbols
+Driver Separate Args(2)
+
+sectorder
+Driver Separate Args(3)
+
 seg1addr
 Driver Separate
 
+segcreate
+Driver Separate Args(3)
+
+segprot
+Driver Separate Args(3)
+
 segs_read_only_addr
 Driver Separate
 
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h	(revision 166309)
+++ gcc/config/darwin.h	(working copy)
@@ -194,20 +194,6 @@ extern GTY(()) int darwin_ms_struct;
     darwin_override_options ();						\
   } while (0)
 
-/* These compiler options take n arguments.  */
-
-#undef  WORD_SWITCH_TAKES_ARG
-#define WORD_SWITCH_TAKES_ARG(STR)              \
-  (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) ? 1 :    \
-   !strcmp (STR, "sectcreate") ? 3 :            \
-   !strcmp (STR, "sectorder") ? 3 :             \
-   !strcmp (STR, "Zsegaddr") ? 2 :              \
-   !strcmp (STR, "segprot") ? 3 :               \
-   !strcmp (STR, "sectalign") ? 3 :             \
-   !strcmp (STR, "sectobjectsymbols") ? 2 :     \
-   !strcmp (STR, "segcreate") ? 3 :             \
-   0)
-
 #define SUBTARGET_C_COMMON_OVERRIDE_OPTIONS do {                        \
     if (flag_mkernel || flag_apple_kext)				\
       {									\
