Patchwork x86 option handling cleanup, use more .opt features

login
register
mail settings
Submitter Joseph S. Myers
Date May 12, 2011, 9:33 p.m.
Message ID <Pine.LNX.4.64.1105122131560.21542@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/95387/
State New
Headers show

Comments

Joseph S. Myers - May 12, 2011, 9:33 p.m.
This patch cleans up x86 option handling to use .opt features where
possible for options with string arguments, instead of decoding those
strings in ix86_option_override_internal.  (The only options with
string arguments that may be generated through target attributes are
-march=, -mtune= and -mfpmath=; I've left cleaning those up for
separate patches.)

The following order of preference for where options are handled
applies:

1. To the extent possible options should be handled through .opt
features.  This means using UInteger for options with unsigned integer
arguments (unless it's useful to support arguments outside the range
of than host int) and Enum for options with enumerated sets of
arguments; it means using Mask and Var where those features suffice to
record the option settings.

2. Where option handling cannot be done purely with .opt features, it
should go in the targetm.handle_option hook as far as possible.  This
includes code checking an integer argument is in a valid range (that
doesn't depend on other options) or setting multiple variables or
flags bits in a way that .opt files cannot describe - anything that
does not involve modifiable global state (only state accessed through
the opts and opts_set pointers) and only depends on a single option,
not on the state of other options that might be passed later on the
command line.

3. Where global state is involved or it is necessary to look at the
final state after all options have been seen, such processing goes in
the targetm.target_option.override.

For making multilib selection work based on logical state, I plan to
split targetm.target_option.override into two hooks, so there will be
(3a) use the hook that can see all options but does not use global
state and (3b) the hook that does use global state.  In preparation
for setting up the new hook, it's desirable to simplify existing
targetm.target_option.override hook definitions first, which is the
function of this patch.

Various options with enumerated string arguments are changed to use
Enum.  Some checking of those arguments was still needed, because the
valid values depend on e.g. the -m64 setting, but that checking now
works with the enumerated values not strings.  I didn't change the
existing logic that -mcmodel=32 isn't allowed with PIC even though the
32-bit default is -mcmodel=32 and the implicit option is allowed with
PIC, though that logic doesn't make sense to me.

Similarly, integer arguments are now handled through UInteger.  This
eliminates several calls to atoi in the compiler.  (We should
eliminate atoi completely and poison it - see PR 44574.  The UInteger
code calls atoi itself, so this patch doesn't actually eliminate the
undefined behavior potential for these options, but it reduces the
number of places needing changing to get rid of atoi.)  UInteger is
stricter (checking the whole argument is made of decimal digits); I
think that increased strictness is what we want consistently for all
integer-argument options.

In the case of -mpc, the three options -mpc32, -mpc64 and -mpc80 are
handled by specs as separate options, and it seemed most appropriate
just to list them as three options in the .opt file as well, rather
than using Enum or validating the values of an integer argument.  (The
compiler doesn't actually use these options at all; they are purely
used by specs when linking.  Properly the compiler *should* use them
to adjust double and long double formats as needed to reflect reduced
precision as applicable.  That is, -mpc64 should have the effects that
the setting of TARGET_96_ROUND_53_LONG_DOUBLE in i386/freebsd.h does,
and -mpc32 should similarly adjust the formats of both float and
double.)

The old handling of -malign-* options (deprecated) had a couple of
problems: it would do nothing for -O0 or -O1 because the
align_functions etc. variables (global_options fields) would have been
set to 1 rather than 0 in that case, and some of the diagnostics had
the wrong option names.  I moved the handling to ix86_handle_option,
so -malign-* and -falign-* now interact in the expected way (the last
option specified wins), and fixed the diagnostics.

ix86_option_override_internal had many diagnostics that tried to allow
for options being passed either on the command line or through
attributes.  Some of these have i18n problems - see PR 46676.  None of
the string-argument options affected by this patch can be passed by
attributes, so those diagnostics (where still needed given the generic
checking of option arguments through increased use of .opt features)
are adjusted just to name the options directly.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Will
commit to trunk in the absence of target maintainer objections.

2011-05-12  Joseph Myers  <joseph@codesourcery.com>

	* config/i386/i386-opts.h: New.
	* gcc/config/i386/i386.c (stringop_alg, ix86_cmodel,
	ix86_asm_dialect, ix86_regparm, ix86_abi, ix86_branch_cost,
	ix86_section_threshold): Remove.
	(ix86_handle_option): Move MAX_CODE_ALIGN define here.  Handle
	OPT_malign_loops_, OPT_malign_jumps_, OPT_malign_functions_ and
	OPT_mbranch_cost_.
	(ix86_option_override_internal): Don't decode strings for options
	other than -march=, -mtune= and -mfpmath=.  Don't allow for
	__attribute__ uses in remaining diagnostics for options with
	string arguments.  Don't check for integer arguments being
	negative.
	* gcc/config/i386/i386.h (enum stringop_alg, enum calling_abi,
	enum tls_dialect, enum cmodel, enum asm_dialect): Move to
	i386-opts.h.
	(ix86_abi, ix86_tls_dialect, ix86_cmodel, ix86_asm_dialect,
	ix86_branch_cost, ix86_section_threshold): Remove.
	* gcc/config/i386/i386.opt (config/i386/i386-opts.h): New
	HeaderInclude.
	(malign-functions=, malign-jumps=, malign-loops=): Use UInteger
	but not Var.
	(masm=): Use Enum and Init.
	(asm_dialect): New Enum and EnumValue entries.
	(mbranch-cost=): Use UInteger.
	(mlarge-data-threshold=): Use UInteger and Init.
	(mcmodel=): Use Enum and Init.
	(cmodel): New Enum and EnumValue entries.
	(mpc): Replace with separate mpc32, mpc64 and mpc80 entries.
	(mpreferred-stack-boundary=, mincoming-stack-boundary=,
	mregparm=): Use UInteger.
	(mstringop-strategy=): Use Enum and Init.
	(stringop_alg): New Enum and EnumValue entries.
	(mtls-dialect=): Use Enum and Init.
	(tls_dialect): New Enum and EnumValue entries.
	(mabi=): Use Enum and Init.
	(calling_abi): New Enum and EnumValue entries.
	(mveclibabi=): Use Enum and Init.
	(ix86_veclibabi): New Enum and EnumValue entries.
Jan Hubicka - May 13, 2011, 9:50 a.m.
> 
> Various options with enumerated string arguments are changed to use
> Enum.  Some checking of those arguments was still needed, because the
> valid values depend on e.g. the -m64 setting, but that checking now
> works with the enumerated values not strings.  I didn't change the
> existing logic that -mcmodel=32 isn't allowed with PIC even though the
> 32-bit default is -mcmodel=32 and the implicit option is allowed with
> PIC, though that logic doesn't make sense to me.

The cmodels on 32bit compilation are not really defined, since ABI does not
really speaks on code models there.  "32" code model is more or less a
placeholder for the code model section. But indeed, allowing it with -fPIC
makes sense.
> 
> 2011-05-12  Joseph Myers  <joseph@codesourcery.com>
> 
> 	* config/i386/i386-opts.h: New.
> 	* gcc/config/i386/i386.c (stringop_alg, ix86_cmodel,
> 	ix86_asm_dialect, ix86_regparm, ix86_abi, ix86_branch_cost,
> 	ix86_section_threshold): Remove.
> 	(ix86_handle_option): Move MAX_CODE_ALIGN define here.  Handle
> 	OPT_malign_loops_, OPT_malign_jumps_, OPT_malign_functions_ and
> 	OPT_mbranch_cost_.
> 	(ix86_option_override_internal): Don't decode strings for options
> 	other than -march=, -mtune= and -mfpmath=.  Don't allow for
> 	__attribute__ uses in remaining diagnostics for options with
> 	string arguments.  Don't check for integer arguments being
> 	negative.
> 	* gcc/config/i386/i386.h (enum stringop_alg, enum calling_abi,
> 	enum tls_dialect, enum cmodel, enum asm_dialect): Move to
> 	i386-opts.h.
> 	(ix86_abi, ix86_tls_dialect, ix86_cmodel, ix86_asm_dialect,
> 	ix86_branch_cost, ix86_section_threshold): Remove.
> 	* gcc/config/i386/i386.opt (config/i386/i386-opts.h): New
> 	HeaderInclude.
> 	(malign-functions=, malign-jumps=, malign-loops=): Use UInteger
> 	but not Var.
> 	(masm=): Use Enum and Init.
> 	(asm_dialect): New Enum and EnumValue entries.
> 	(mbranch-cost=): Use UInteger.
> 	(mlarge-data-threshold=): Use UInteger and Init.
> 	(mcmodel=): Use Enum and Init.
> 	(cmodel): New Enum and EnumValue entries.
> 	(mpc): Replace with separate mpc32, mpc64 and mpc80 entries.
> 	(mpreferred-stack-boundary=, mincoming-stack-boundary=,
> 	mregparm=): Use UInteger.
> 	(mstringop-strategy=): Use Enum and Init.
> 	(stringop_alg): New Enum and EnumValue entries.
> 	(mtls-dialect=): Use Enum and Init.
> 	(tls_dialect): New Enum and EnumValue entries.
> 	(mabi=): Use Enum and Init.
> 	(calling_abi): New Enum and EnumValue entries.
> 	(mveclibabi=): Use Enum and Init.
> 	(ix86_veclibabi): New Enum and EnumValue entries.
OK
Thanks for the hard work!
Honza

Patch

Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(revision 173651)
+++ gcc/config/i386/i386.h	(working copy)
@@ -79,18 +79,7 @@  see the files COPYING3 and COPYING.RUNTI
 
 #include "config/vxworks-dummy.h"
 
-/* Algorithm to expand string function with.  */
-enum stringop_alg
-{
-   no_stringop,
-   libcall,
-   rep_prefix_1_byte,
-   rep_prefix_4_byte,
-   rep_prefix_8_byte,
-   loop_1_byte,
-   loop,
-   unrolled_loop
-};
+#include "config/i386/i386-opts.h"
 
 #define MAX_STRINGOP_ALGS 4
 
@@ -506,16 +495,6 @@  extern tree x86_mfence;
 /* This is re-defined by cygming.h.  */
 #define TARGET_SEH 0
 
-/* Available call abi.  */
-enum calling_abi
-{
-  SYSV_ABI = 0,
-  MS_ABI = 1
-};
-
-/* The abi used by target.  */
-extern enum calling_abi ix86_abi;
-
 /* The default abi used by target.  */
 #define DEFAULT_ABI SYSV_ABI
 
@@ -2058,42 +2037,13 @@  enum fpmath_unit
 
 extern enum fpmath_unit ix86_fpmath;
 
-enum tls_dialect
-{
-  TLS_DIALECT_GNU,
-  TLS_DIALECT_GNU2,
-  TLS_DIALECT_SUN
-};
-
-extern enum tls_dialect ix86_tls_dialect;
-
-enum cmodel {
-  CM_32,	/* The traditional 32-bit ABI.  */
-  CM_SMALL,	/* Assumes all code and data fits in the low 31 bits.  */
-  CM_KERNEL,	/* Assumes all code and data fits in the high 31 bits.  */
-  CM_MEDIUM,	/* Assumes code fits in the low 31 bits; data unlimited.  */
-  CM_LARGE,	/* No assumptions.  */
-  CM_SMALL_PIC,	/* Assumes code+data+got/plt fits in a 31 bit region.  */
-  CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region.  */
-  CM_LARGE_PIC	/* No assumptions.  */
-};
-
-extern enum cmodel ix86_cmodel;
-
 /* Size of the RED_ZONE area.  */
 #define RED_ZONE_SIZE 128
 /* Reserved area of the red zone for temporaries.  */
 #define RED_ZONE_RESERVE 8
 
-enum asm_dialect {
-  ASM_ATT,
-  ASM_INTEL
-};
-
-extern enum asm_dialect ix86_asm_dialect;
 extern unsigned int ix86_preferred_stack_boundary;
 extern unsigned int ix86_incoming_stack_boundary;
-extern int ix86_branch_cost, ix86_section_threshold;
 
 /* Smallest class containing REGNO.  */
 extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
Index: gcc/config/i386/i386-opts.h
===================================================================
--- gcc/config/i386/i386-opts.h	(revision 0)
+++ gcc/config/i386/i386-opts.h	(revision 0)
@@ -0,0 +1,79 @@ 
+/* Definitions for option handling for IA-32.
+   Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef I386_OPTS_H
+#define I386_OPTS_H
+
+/* Algorithm to expand string function with.  */
+enum stringop_alg
+{
+   no_stringop,
+   libcall,
+   rep_prefix_1_byte,
+   rep_prefix_4_byte,
+   rep_prefix_8_byte,
+   loop_1_byte,
+   loop,
+   unrolled_loop
+};
+
+/* Available call abi.  */
+enum calling_abi
+{
+  SYSV_ABI = 0,
+  MS_ABI = 1
+};
+
+enum tls_dialect
+{
+  TLS_DIALECT_GNU,
+  TLS_DIALECT_GNU2,
+  TLS_DIALECT_SUN
+};
+
+enum cmodel {
+  CM_32,	/* The traditional 32-bit ABI.  */
+  CM_SMALL,	/* Assumes all code and data fits in the low 31 bits.  */
+  CM_KERNEL,	/* Assumes all code and data fits in the high 31 bits.  */
+  CM_MEDIUM,	/* Assumes code fits in the low 31 bits; data unlimited.  */
+  CM_LARGE,	/* No assumptions.  */
+  CM_SMALL_PIC,	/* Assumes code+data+got/plt fits in a 31 bit region.  */
+  CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region.  */
+  CM_LARGE_PIC	/* No assumptions.  */
+};
+
+enum asm_dialect {
+  ASM_ATT,
+  ASM_INTEL
+};
+
+enum ix86_veclibabi {
+  ix86_veclibabi_type_none,
+  ix86_veclibabi_type_svml,
+  ix86_veclibabi_type_acml
+};
+
+#endif
Index: gcc/config/i386/i386.opt
===================================================================
--- gcc/config/i386/i386.opt	(revision 173651)
+++ gcc/config/i386/i386.opt	(working copy)
@@ -19,6 +19,9 @@ 
 ; along with GCC; see the file COPYING3.  If not see
 ; <http://www.gnu.org/licenses/>.
 
+HeaderInclude
+config/i386/i386-opts.h
+
 ; Bit flags that specify the ISA we are compiling for.
 Variable
 int ix86_isa_flags = TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_ISA_DEFAULT
@@ -87,15 +90,15 @@  Target Report Mask(ALIGN_DOUBLE) Save
 Align some doubles on dword boundary
 
 malign-functions=
-Target RejectNegative Joined Var(ix86_align_funcs_string)
+Target RejectNegative Joined UInteger
 Function starts are aligned to this power of 2
 
 malign-jumps=
-Target RejectNegative Joined Var(ix86_align_jumps_string)
+Target RejectNegative Joined UInteger
 Jump targets are aligned to this power of 2
 
 malign-loops=
-Target RejectNegative Joined Var(ix86_align_loops_string)
+Target RejectNegative Joined UInteger
 Loop code aligned to this power of 2
 
 malign-stringops
@@ -107,21 +110,50 @@  Target RejectNegative Joined Var(ix86_ar
 Generate code for given CPU
 
 masm=
-Target RejectNegative Joined Var(ix86_asm_string)
+Target RejectNegative Joined Enum(asm_dialect) Var(ix86_asm_dialect) Init(ASM_ATT)
 Use given assembler dialect
 
+Enum
+Name(asm_dialect) Type(enum asm_dialect)
+Known assembler dialects (for use with the -masm-dialect= option):
+
+EnumValue
+Enum(asm_dialect) String(intel) Value(ASM_INTEL)
+
+EnumValue
+Enum(asm_dialect) String(att) Value(ASM_ATT)
+
 mbranch-cost=
-Target RejectNegative Joined Var(ix86_branch_cost_string)
+Target RejectNegative Joined UInteger Var(ix86_branch_cost)
 Branches are this expensive (1-5, arbitrary units)
 
 mlarge-data-threshold=
-Target RejectNegative Joined Var(ix86_section_threshold_string)
+Target RejectNegative Joined UInteger Var(ix86_section_threshold) Init(65536)
 Data greater than given threshold will go into .ldata section in x86-64 medium model
 
 mcmodel=
-Target RejectNegative Joined Var(ix86_cmodel_string)
+Target RejectNegative Joined Enum(cmodel) Var(ix86_cmodel) Init(CM_32)
 Use given x86-64 code model
 
+Enum
+Name(cmodel) Type(enum cmodel)
+Known code models (for use with the -mcmodel= option):
+
+EnumValue
+Enum(cmodel) String(small) Value(CM_SMALL)
+
+EnumValue
+Enum(cmodel) String(medium) Value(CM_MEDIUM)
+
+EnumValue
+Enum(cmodel) String(large) Value(CM_LARGE)
+
+EnumValue
+Enum(cmodel) String(32) Value(CM_32)
+
+EnumValue
+Enum(cmodel) String(kernel) Value(CM_KERNEL)
+
 mcpu=
 Target RejectNegative Joined Undocumented Alias(mtune=) Warn(%<-mcpu=%> is deprecated; use %<-mtune=%> or %<-march=%> instead)
 
@@ -181,16 +213,24 @@  momit-leaf-frame-pointer
 Target Report Mask(OMIT_LEAF_FRAME_POINTER) Save
 Omit the frame pointer in leaf functions
 
-mpc
-Target RejectNegative Report Joined Var(ix87_precision_string)
-Set 80387 floating-point precision (-mpc32, -mpc64, -mpc80)
+mpc32
+Target RejectNegative Report
+Set 80387 floating-point precision to 32-bit
+
+mpc64
+Target RejectNegative Report
+Set 80387 floating-point precision to 64-bit
+
+mpc80
+Target RejectNegative Report
+Set 80387 floating-point precision to 80-bit
 
 mpreferred-stack-boundary=
-Target RejectNegative Joined Var(ix86_preferred_stack_boundary_string)
+Target RejectNegative Joined UInteger Var(ix86_preferred_stack_boundary_arg)
 Attempt to keep stack aligned to this power of 2
 
 mincoming-stack-boundary=
-Target RejectNegative Joined Var(ix86_incoming_stack_boundary_string)
+Target RejectNegative Joined UInteger Var(ix86_incoming_stack_boundary_arg)
 Assume incoming stack aligned to this power of 2
 
 mpush-args
@@ -202,7 +242,7 @@  Target RejectNegative Report InverseMask
 Use red-zone in the x86-64 code
 
 mregparm=
-Target RejectNegative Joined Var(ix86_regparm_string)
+Target RejectNegative Joined UInteger Var(ix86_regparm)
 Number of registers used to pass integer arguments
 
 mrtd
@@ -226,13 +266,48 @@  Target Report Mask(STACK_PROBE) Save
 Enable stack probing
 
 mstringop-strategy=
-Target RejectNegative Joined Var(ix86_stringop_string)
+Target RejectNegative Joined Enum(stringop_alg) Var(ix86_stringop_alg) Init(no_stringop)
 Chose strategy to generate stringop using
 
+Enum
+Name(stringop_alg) Type(enum stringop_alg)
+Valid arguments to -mstringop-strategy=:
+
+EnumValue
+Enum(stringop_alg) String(rep_byte) Value(rep_prefix_1_byte)
+
+EnumValue
+Enum(stringop_alg) String(libcall) Value(libcall)
+
+EnumValue
+Enum(stringop_alg) String(rep_4byte) Value(rep_prefix_4_byte)
+
+EnumValue
+Enum(stringop_alg) String(rep_8byte) Value(rep_prefix_8_byte)
+
+EnumValue
+Enum(stringop_alg) String(byte_loop) Value(loop_1_byte)
+
+EnumValue
+Enum(stringop_alg) String(loop) Value(loop)
+
+EnumValue
+Enum(stringop_alg) String(unrolled_loop) Value(unrolled_loop)
+
 mtls-dialect=
-Target RejectNegative Joined Var(ix86_tls_dialect_string)
+Target RejectNegative Joined Var(ix86_tls_dialect) Enum(tls_dialect) Init(TLS_DIALECT_GNU)
 Use given thread-local storage dialect
 
+Enum
+Name(tls_dialect) Type(enum tls_dialect)
+Known TLS dialects (for use with the -mtls-dialect= option):
+
+EnumValue
+Enum(tls_dialect) String(gnu) Value(TLS_DIALECT_GNU)
+
+EnumValue
+Enum(tls_dialect) String(gnu2) Value(TLS_DIALECT_GNU2)
+
 mtls-direct-seg-refs
 Target Report Mask(TLS_DIRECT_SEG_REFS)
 Use direct references against %gs when accessing tls data
@@ -242,13 +317,33 @@  Target RejectNegative Joined Var(ix86_tu
 Schedule code for given CPU
 
 mabi=
-Target RejectNegative Joined Var(ix86_abi_string)
+Target RejectNegative Joined Var(ix86_abi) Enum(calling_abi) Init(SYSV_ABI)
 Generate code that conforms to the given ABI
 
+Enum
+Name(calling_abi) Type(enum calling_abi)
+Known ABIs (for use with the -mabi= option):
+
+EnumValue
+Enum(calling_abi) String(sysv) Value(SYSV_ABI)
+
+EnumValue
+Enum(calling_abi) String(ms) Value(MS_ABI)
+
 mveclibabi=
-Target RejectNegative Joined Var(ix86_veclibabi_string)
+Target RejectNegative Joined Var(ix86_veclibabi_type) Enum(ix86_veclibabi) Init(ix86_veclibabi_type_none)
 Vector library ABI to use
 
+Enum
+Name(ix86_veclibabi) Type(enum ix86_veclibabi)
+Known vectorization library ABIs (for use with the -mveclibabi= option):
+
+EnumValue
+Enum(ix86_veclibabi) String(svml) Value(ix86_veclibabi_type_svml)
+
+EnumValue
+Enum(ix86_veclibabi) String(acml) Value(ix86_veclibabi_type_acml)
+
 mvect8-ret-in-mem
 Target Report Mask(VECT8_RETURNS) Save
 Return 8-byte vectors in memory
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 173651)
+++ gcc/config/i386/i386.c	(working copy)
@@ -2120,8 +2120,6 @@  static const unsigned int x86_arch_alway
   = m_PENT | m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_PENT4
     | m_NOCONA | m_CORE2I7 | m_GENERIC;
 
-static enum stringop_alg stringop_alg = no_stringop;
-
 /* In case the average insn count for single function invocation is
    lower than this constant, emit fast (but longer) prologue and
    epilogue code.  */
@@ -2327,13 +2325,6 @@  struct ix86_frame
   bool save_regs_using_mov;
 };
 
-/* Code model option.  */
-enum cmodel ix86_cmodel;
-/* Asm dialect.  */
-enum asm_dialect ix86_asm_dialect = ASM_ATT;
-/* TLS dialects.  */
-enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
-
 /* Which unit we are generating floating point math for.  */
 enum fpmath_unit ix86_fpmath;
 
@@ -2349,9 +2340,6 @@  enum processor_type ix86_arch;
 /* true if sse prefetch instruction is not NOOP.  */
 int x86_prefetch_sse;
 
-/* ix86_regparm_string as a number */
-static int ix86_regparm;
-
 /* -mstackrealign option */
 static const char ix86_force_align_arg_pointer_string[]
   = "force_align_arg_pointer";
@@ -2380,21 +2368,10 @@  static unsigned int ix86_default_incomin
 /* Alignment for incoming stack boundary in bits.  */
 unsigned int ix86_incoming_stack_boundary;
 
-/* The abi used by target.  */
-enum calling_abi ix86_abi;
-
-/* Values 1-5: see jump.c */
-int ix86_branch_cost;
-
 /* Calling abi specific va_list type nodes.  */
 static GTY(()) tree sysv_va_list_type_node;
 static GTY(()) tree ms_va_list_type_node;
 
-/* Variables which are this size or smaller are put in the data/bss
-   or ldata/lbss sections.  */
-
-int ix86_section_threshold = 65536;
-
 /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
 char internal_label_prefix[16];
 int internal_label_prefix_len;
@@ -2688,7 +2665,7 @@  static bool
 ix86_handle_option (struct gcc_options *opts,
 		    struct gcc_options *opts_set ATTRIBUTE_UNUSED,
 		    const struct cl_decoded_option *decoded,
-		    location_t loc ATTRIBUTE_UNUSED)
+		    location_t loc)
 {
   size_t code = decoded->opt_index;
   int value = decoded->value;
@@ -3059,6 +3036,45 @@  ix86_handle_option (struct gcc_options *
 	}
       return true;
 
+  /* Comes from final.c -- no real reason to change it.  */
+#define MAX_CODE_ALIGN 16
+
+    case OPT_malign_loops_:
+      warning_at (loc, 0, "-malign-loops is obsolete, use -falign-loops");
+      if (value > MAX_CODE_ALIGN)
+	error_at (loc, "-malign-loops=%d is not between 0 and %d",
+		  value, MAX_CODE_ALIGN);
+      else
+	opts->x_align_loops = 1 << value;
+      return true;
+
+    case OPT_malign_jumps_:
+      warning_at (loc, 0, "-malign-jumps is obsolete, use -falign-jumps");
+      if (value > MAX_CODE_ALIGN)
+	error_at (loc, "-malign-jumps=%d is not between 0 and %d",
+		  value, MAX_CODE_ALIGN);
+      else
+	opts->x_align_jumps = 1 << value;
+      return true;
+
+    case OPT_malign_functions_:
+      warning_at (loc, 0,
+		  "-malign-functions is obsolete, use -falign-functions");
+      if (value > MAX_CODE_ALIGN)
+	error_at (loc, "-malign-functions=%d is not between 0 and %d",
+		  value, MAX_CODE_ALIGN);
+      else
+	opts->x_align_functions = 1 << value;
+      return true;
+
+    case OPT_mbranch_cost_:
+      if (value > 5)
+	{
+	  error_at (loc, "-mbranch-cost=%d is not between 0 and 5", value);
+	  opts->x_ix86_branch_cost = 5;
+	}
+      return true;
+
     default:
       return true;
     }
@@ -3305,9 +3321,6 @@  ix86_option_override_internal (bool main
   const char *suffix;
   const char *sw;
 
-  /* Comes from final.c -- no real reason to change it.  */
-#define MAX_CODE_ALIGN 16
-
   enum pta_flags
     {
       PTA_SSE = 1 << 0,
@@ -3530,27 +3543,11 @@  ix86_option_override_internal (bool main
 	}
     }
 
-  if (ix86_stringop_string)
+  if (ix86_stringop_alg == rep_prefix_8_byte && !TARGET_64BIT)
     {
-      if (!strcmp (ix86_stringop_string, "rep_byte"))
-	stringop_alg = rep_prefix_1_byte;
-      else if (!strcmp (ix86_stringop_string, "libcall"))
-	stringop_alg = libcall;
-      else if (!strcmp (ix86_stringop_string, "rep_4byte"))
-	stringop_alg = rep_prefix_4_byte;
-      else if (!strcmp (ix86_stringop_string, "rep_8byte")
-	       && TARGET_64BIT)
-	/* rep; movq isn't available in 32-bit code.  */
-	stringop_alg = rep_prefix_8_byte;
-      else if (!strcmp (ix86_stringop_string, "byte_loop"))
-	stringop_alg = loop_1_byte;
-      else if (!strcmp (ix86_stringop_string, "loop"))
-	stringop_alg = loop;
-      else if (!strcmp (ix86_stringop_string, "unrolled_loop"))
-	stringop_alg = unrolled_loop;
-      else
-	error ("bad value (%s) for %sstringop-strategy=%s %s",
-	       ix86_stringop_string, prefix, suffix, sw);
+      /* rep; movq isn't available in 32-bit code.  */
+      error ("-mstringop-strategy=rep_8byte not supported for 32-bit code");
+      ix86_stringop_alg = no_stringop;
     }
 
   if (!ix86_arch_string)
@@ -3558,37 +3555,62 @@  ix86_option_override_internal (bool main
   else
     ix86_arch_specified = 1;
 
-  /* Validate -mabi= value.  */
-  if (ix86_abi_string)
-    {
-      if (strcmp (ix86_abi_string, "sysv") == 0)
-	ix86_abi = SYSV_ABI;
-      else if (strcmp (ix86_abi_string, "ms") == 0)
-	ix86_abi = MS_ABI;
-      else
-	error ("unknown ABI (%s) for %sabi=%s %s",
-	       ix86_abi_string, prefix, suffix, sw);
-    }
-  else
+  if (!global_options_set.x_ix86_abi)
     ix86_abi = DEFAULT_ABI;
 
-  if (ix86_cmodel_string != 0)
+  if (global_options_set.x_ix86_cmodel)
     {
-      if (!strcmp (ix86_cmodel_string, "small"))
-	ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
-      else if (!strcmp (ix86_cmodel_string, "medium"))
-	ix86_cmodel = flag_pic ? CM_MEDIUM_PIC : CM_MEDIUM;
-      else if (!strcmp (ix86_cmodel_string, "large"))
-	ix86_cmodel = flag_pic ? CM_LARGE_PIC : CM_LARGE;
-      else if (flag_pic)
-	error ("code model %s does not support PIC mode", ix86_cmodel_string);
-      else if (!strcmp (ix86_cmodel_string, "32"))
-	ix86_cmodel = CM_32;
-      else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
-	ix86_cmodel = CM_KERNEL;
-      else
-	error ("bad value (%s) for %scmodel=%s %s",
-	       ix86_cmodel_string, prefix, suffix, sw);
+      switch (ix86_cmodel)
+	{
+	case CM_SMALL:
+	case CM_SMALL_PIC:
+	  if (flag_pic)
+	    ix86_cmodel = CM_SMALL_PIC;
+	  if (!TARGET_64BIT)
+	    error ("code model %qs not supported in the %s bit mode",
+		   "small", "32");
+	  break;
+
+	case CM_MEDIUM:
+	case CM_MEDIUM_PIC:
+	  if (flag_pic)
+	    ix86_cmodel = CM_MEDIUM_PIC;
+	  if (!TARGET_64BIT)
+	    error ("code model %qs not supported in the %s bit mode",
+		   "medium", "32");
+	  break;
+
+	case CM_LARGE:
+	case CM_LARGE_PIC:
+	  if (flag_pic)
+	    ix86_cmodel = CM_LARGE_PIC;
+	  if (!TARGET_64BIT)
+	    error ("code model %qs not supported in the %s bit mode",
+		   "large", "32");
+	  break;
+
+	case CM_32:
+	  if (flag_pic)
+	    error ("code model %s does not support PIC mode", "32");
+	  if (TARGET_64BIT)
+	    error ("code model %qs not supported in the %s bit mode",
+		   "32", "64");
+	  break;
+
+	case CM_KERNEL:
+	  if (flag_pic)
+	    {
+	      error ("code model %s does not support PIC mode", "kernel");
+	      ix86_cmodel = CM_32;
+	    }
+	  if (!TARGET_64BIT)
+	    error ("code model %qs not supported in the %s bit mode",
+		   "kernel", "32");
+	  break;
+
+	default:
+	  gcc_unreachable ();
+	}
     }
   else
     {
@@ -3603,20 +3625,11 @@  ix86_option_override_internal (bool main
       else
         ix86_cmodel = CM_32;
     }
-  if (ix86_asm_string != 0)
+  if (TARGET_MACHO && ix86_asm_dialect == ASM_INTEL)
     {
-      if (! TARGET_MACHO
-	  && !strcmp (ix86_asm_string, "intel"))
-	ix86_asm_dialect = ASM_INTEL;
-      else if (!strcmp (ix86_asm_string, "att"))
-	ix86_asm_dialect = ASM_ATT;
-      else
-	error ("bad value (%s) for %sasm=%s %s",
-	       ix86_asm_string, prefix, suffix, sw);
-    }
-  if ((TARGET_64BIT == 0) != (ix86_cmodel == CM_32))
-    error ("code model %qs not supported in the %s bit mode",
-	   ix86_cmodel_string, TARGET_64BIT ? "64" : "32");
+      error ("-masm=intel not supported in this configuration");
+      ix86_asm_dialect = ASM_ATT;
+    }
   if ((TARGET_64BIT != 0) != ((ix86_isa_flags & OPTION_MASK_ISA_64BIT) != 0))
     sorry ("%i-bit mode not compiled in",
 	   (ix86_isa_flags & OPTION_MASK_ISA_64BIT) ? 64 : 32);
@@ -3836,67 +3849,19 @@  ix86_option_override_internal (bool main
   init_machine_status = ix86_init_machine_status;
 
   /* Validate -mregparm= value.  */
-  if (ix86_regparm_string)
+  if (global_options_set.x_ix86_regparm)
     {
       if (TARGET_64BIT)
-	warning (0, "%sregparm%s is ignored in 64-bit mode", prefix, suffix);
-      i = atoi (ix86_regparm_string);
-      if (i < 0 || i > REGPARM_MAX)
-	error ("%sregparm=%d%s is not between 0 and %d",
-	       prefix, i, suffix, REGPARM_MAX);
-      else
-	ix86_regparm = i;
-    }
-  if (TARGET_64BIT)
-    ix86_regparm = REGPARM_MAX;
-
-  /* If the user has provided any of the -malign-* options,
-     warn and use that value only if -falign-* is not set.
-     Remove this code in GCC 3.2 or later.  */
-  if (ix86_align_loops_string)
-    {
-      warning (0, "%salign-loops%s is obsolete, use -falign-loops%s",
-	       prefix, suffix, suffix);
-      if (align_loops == 0)
+	warning (0, "-mregparm is ignored in 64-bit mode");
+      if (ix86_regparm > REGPARM_MAX)
 	{
-	  i = atoi (ix86_align_loops_string);
-	  if (i < 0 || i > MAX_CODE_ALIGN)
-	    error ("%salign-loops=%d%s is not between 0 and %d",
-		   prefix, i, suffix, MAX_CODE_ALIGN);
-	  else
-	    align_loops = 1 << i;
-	}
-    }
-
-  if (ix86_align_jumps_string)
-    {
-      warning (0, "%salign-jumps%s is obsolete, use -falign-jumps%s",
-	       prefix, suffix, suffix);
-      if (align_jumps == 0)
-	{
-	  i = atoi (ix86_align_jumps_string);
-	  if (i < 0 || i > MAX_CODE_ALIGN)
-	    error ("%salign-loops=%d%s is not between 0 and %d",
-		   prefix, i, suffix, MAX_CODE_ALIGN);
-	  else
-	    align_jumps = 1 << i;
-	}
-    }
-
-  if (ix86_align_funcs_string)
-    {
-      warning (0, "%salign-functions%s is obsolete, use -falign-functions%s",
-	       prefix, suffix, suffix);
-      if (align_functions == 0)
-	{
-	  i = atoi (ix86_align_funcs_string);
-	  if (i < 0 || i > MAX_CODE_ALIGN)
-	    error ("%salign-loops=%d%s is not between 0 and %d",
-		   prefix, i, suffix, MAX_CODE_ALIGN);
-	  else
-	    align_functions = 1 << i;
+	  error ("-mregparm=%d is not between 0 and %d",
+		 ix86_regparm, REGPARM_MAX);
+	  ix86_regparm = 0;
 	}
     }
+  if (TARGET_64BIT)
+    ix86_regparm = REGPARM_MAX;
 
   /* Default align_* from the processor table.  */
   if (align_loops == 0)
@@ -3914,42 +3879,9 @@  ix86_option_override_internal (bool main
       align_functions = processor_target_table[ix86_tune].align_func;
     }
 
-  /* Validate -mbranch-cost= value, or provide default.  */
-  ix86_branch_cost = ix86_cost->branch_cost;
-  if (ix86_branch_cost_string)
-    {
-      i = atoi (ix86_branch_cost_string);
-      if (i < 0 || i > 5)
-	error ("%sbranch-cost=%d%s is not between 0 and 5", prefix, i, suffix);
-      else
-	ix86_branch_cost = i;
-    }
-  if (ix86_section_threshold_string)
-    {
-      i = atoi (ix86_section_threshold_string);
-      if (i < 0)
-	error ("%slarge-data-threshold=%d%s is negative", prefix, i, suffix);
-      else
-	ix86_section_threshold = i;
-    }
-
-  if (ix86_tls_dialect_string)
-    {
-      if (strcmp (ix86_tls_dialect_string, "gnu") == 0)
-	ix86_tls_dialect = TLS_DIALECT_GNU;
-      else if (strcmp (ix86_tls_dialect_string, "gnu2") == 0)
-	ix86_tls_dialect = TLS_DIALECT_GNU2;
-      else
-	error ("bad value (%s) for %stls-dialect=%s %s",
-	       ix86_tls_dialect_string, prefix, suffix, sw);
-    }
-
-  if (ix87_precision_string)
-    {
-      i = atoi (ix87_precision_string);
-      if (i != 32 && i != 64 && i != 80)
-	error ("pc%d is not valid precision setting (32, 64 or 80)", i);
-    }
+  /* Provide default for -mbranch-cost= value.  */
+  if (!global_options_set.x_ix86_branch_cost)
+    ix86_branch_cost = ix86_cost->branch_cost;
 
   if (TARGET_64BIT)
     {
@@ -4015,23 +3947,24 @@  ix86_option_override_internal (bool main
   /* Validate -mpreferred-stack-boundary= value or default it to
      PREFERRED_STACK_BOUNDARY_DEFAULT.  */
   ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
-  if (ix86_preferred_stack_boundary_string)
+  if (global_options_set.x_ix86_preferred_stack_boundary_arg)
     {
       int min = (TARGET_64BIT ? 4 : 2);
       int max = (TARGET_SEH ? 4 : 12);
 
-      i = atoi (ix86_preferred_stack_boundary_string);
-      if (i < min || i > max)
+      if (ix86_preferred_stack_boundary_arg < min
+	  || ix86_preferred_stack_boundary_arg > max)
 	{
 	  if (min == max)
-	    error ("%spreferred-stack-boundary%s is not supported "
-		   "for this target", prefix, suffix);
+	    error ("-mpreferred-stack-boundary is not supported "
+		   "for this target");
 	  else
-	    error ("%spreferred-stack-boundary=%d%s is not between %d and %d",
-		   prefix, i, suffix, min, max);
+	    error ("-mpreferred-stack-boundary=%d is not between %d and %d",
+		   ix86_preferred_stack_boundary_arg, min, max);
 	}
       else
-	ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
+	ix86_preferred_stack_boundary
+	  = (1 << ix86_preferred_stack_boundary_arg) * BITS_PER_UNIT;
     }
 
   /* Set the default value for -mstackrealign.  */
@@ -4043,15 +3976,16 @@  ix86_option_override_internal (bool main
   /* Validate -mincoming-stack-boundary= value or default it to
      MIN_STACK_BOUNDARY/PREFERRED_STACK_BOUNDARY.  */
   ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
-  if (ix86_incoming_stack_boundary_string)
+  if (global_options_set.x_ix86_incoming_stack_boundary_arg)
     {
-      i = atoi (ix86_incoming_stack_boundary_string);
-      if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
+      if (ix86_incoming_stack_boundary_arg < (TARGET_64BIT ? 4 : 2)
+	  || ix86_incoming_stack_boundary_arg > 12)
 	error ("-mincoming-stack-boundary=%d is not between %d and 12",
-	       i, TARGET_64BIT ? 4 : 2);
+	       ix86_incoming_stack_boundary_arg, TARGET_64BIT ? 4 : 2);
       else
 	{
-	  ix86_user_incoming_stack_boundary = (1 << i) * BITS_PER_UNIT;
+	  ix86_user_incoming_stack_boundary
+	    = (1 << ix86_incoming_stack_boundary_arg) * BITS_PER_UNIT;
 	  ix86_incoming_stack_boundary
 	    = ix86_user_incoming_stack_boundary;
 	}
@@ -4106,17 +4040,20 @@  ix86_option_override_internal (bool main
     target_flags &= ~MASK_FLOAT_RETURNS;
 
   /* Use external vectorized library in vectorizing intrinsics.  */
-  if (ix86_veclibabi_string)
-    {
-      if (strcmp (ix86_veclibabi_string, "svml") == 0)
+  if (global_options_set.x_ix86_veclibabi_type)
+    switch (ix86_veclibabi_type)
+      {
+      case ix86_veclibabi_type_svml:
 	ix86_veclib_handler = ix86_veclibabi_svml;
-      else if (strcmp (ix86_veclibabi_string, "acml") == 0)
+	break;
+
+      case ix86_veclibabi_type_acml:
 	ix86_veclib_handler = ix86_veclibabi_acml;
-      else
-	error ("unknown vectorization library ABI type (%s) for "
-	       "%sveclibabi=%s %s", ix86_veclibabi_string,
-	       prefix, suffix, sw);
-    }
+	break;
+
+      default:
+	gcc_unreachable ();
+      }
 
   if ((!USE_IX86_FRAME_POINTER
        || (x86_accumulate_outgoing_args & ix86_tune_mask))
@@ -20797,8 +20734,8 @@  decide_alg (HOST_WIDE_INT count, HOST_WI
     algs = &cost->memset[TARGET_64BIT != 0];
   else
     algs = &cost->memcpy[TARGET_64BIT != 0];
-  if (stringop_alg != no_stringop && ALG_USABLE_P (stringop_alg))
-    return stringop_alg;
+  if (ix86_stringop_alg != no_stringop && ALG_USABLE_P (ix86_stringop_alg))
+    return ix86_stringop_alg;
   /* rep; movq or rep; movl is the smallest variant.  */
   else if (!optimize_for_speed)
     {