At line 605 above, set_target_switch handles options related to compile target. All these options begins with “-m”.
3829 void
3830 set_target_switch (const char *name) in toplev.c
3831 {
3832 size_t j;
3833 int valid_target_option = 0;
3834
3835 for (j = 0; j < ARRAY_SIZE (target_switches); j++)
3836 if (!strcmp (target_switches [j].name, name))
3837 {
3838 if (target_switches [j].value < 0)
3839 target_flags &= ~target_switches[j].value;
3840 else
3841 target_flags |= target_switches [j].value;
3842 if (name[0] != 0)
3843 {
3844 if (target_switches [j].value < 0)
3845 target_flags_explicit |= -target_switches [j].value;
3846 else
3847 target_flags_explicit |= target_switches [j].value;
3848 }
3849 valid_target_option = 1;
3850 }
3851
3852 #ifdef TARGET_OPTIONS
3853 if (!valid_target_option)
3854 for (j = 0; j < ARRAY_SIZE (target_options); j++)
3855 {
3856 int len = strlen (target_options [j].prefix);
3857 if (target_options [j].value)
3858 {
3859 if (!strcmp (target_options [j].prefix, name))
3860 {
3861 *target_options [j].variable = target_options [j].value;
3862 valid_target_option = 1;
3863 }
3864 }
3865 else
3866 {
3867 if (!strncmp (target_options [j].prefix, name, len))
3868 {
3869 *target_options [j].variable = name + len;
3870 valid_target_option = 1;
3871 }
3872 }
3873 }
3874 #endif
3875
3876 if (!valid_target_option)
3877 error ("invalid option `%s'", name);
3878 }
Above, at line 3835, target_switches is defined toplev.c as following.
1166 static const struct in toplev.c
1167 {
1168 const char *const name;
1169 const int value;
1170 const char *const description;
1171 }
1172 target_switches[] = TARGET_SWITCHES;
target_switches gets its content from TARGET_SWITCHES which is platform specified, and for x86 system, target related switches are displayed in following table and is defined in i386.h.
Option Name
|
Value |
Description |
80387 |
MASK_80387 |
Use hardware fp |
no-80387 |
-MASK_80387 |
Do not use hardware fp |
hard-float |
MASK_80387 |
Use hardware fp |
soft-float |
-MASK_80387 |
Do not use hardware fp |
no-soft-float |
MASK_80387 |
Use hardware fp |
386 |
0 |
"" /*Deprecated.*/ |
486 |
0 |
"" /*Deprecated.*/ |
pentium |
0 |
"" /*Deprecated.*/ |
pentiumpro |
0 |
"" /*Deprecated.*/ |
pni |
0 |
"" |
no-pni |
0 |
"" /*Deprecated.*/ |
intel-syntax |
0 |
"" /*Deprecated.*/ |
no-intel-syntax |
0 |
"" /*Deprecated.*/ |
rtd |
MASK_RTD |
Alternate calling convention |
no-rtd |
-MASK_RTD |
Use normal calling convention |
align-double |
MASK_ALIGN_DOUBLE |
Align some doubles on dword boundary |
no-align-double |
-MASK_ALIGN_DOUBLE |
Align doubles on word boundary |
svr3-shlib |
MASK_SVR3_SHLIB |
Uninitialized locals in .bss |
no-svr3-shlib |
-MASK_SVR3_SHLIB |
Uninitialized locals in .data |
ieee-fp |
MASK_IEEE_FP |
Use IEEE math for fp comparisons |
no-ieee-fp |
-MASK_IEEE_FP |
Do not use IEEE math for fp comparisons |
fp-ret-in-387 |
MASK_FLOAT_RETURNS |
Return values of functions in FPU registers |
no-fp-ret-in-387 |
-MASK_FLOAT_RETURNS |
Do not return values of functions in FPU registers |
no-fancy-math-387 |
MASK_NO_FANCY_MATH_387 |
Do not generate sin, cos, sqrt for FPU |
fancy-math-387 |
-MASK_NO_FANCY_MATH_387 |
Generate sin, cos, sqrt for FPU |
omit-leaf-frame-pointer |
MASK_OMIT_LEAF_FRAME_POINTER |
Omit the frame pointer in leaf functions (i.e., one which makes no calls) |
no-omit-leaf-frame-pointer |
-MASK_OMIT_LEAF_FRAME_POINTER |
"" |
stack-arg-probe |
MASK_STACK_PROBE |
Enable stack probing |
no-stack-arg-probe |
-MASK_STACK_PROBE |
"" |
windows |
0 |
0 /* undocumented */ |
dll |
0 |
0 /* undocumented */ |
align-stringops |
-MASK_NO_ALIGN_STROPS |
Align destination of the string operations |
no-align-stringops |
MASK_NO_ALIGN_STROPS |
Do not align destination of the string operations |
inline-all-stringops |
MASK_INLINE_ALL_STROPS |
Inline all known string operations |
no-inline-all-stringops |
-MASK_INLINE_ALL_STROPS |
Do not inline all known string operations |
push-args |
-MASK_NO_PUSH_ARGS |
Use push instructions to save outgoing arguments |
no-push-args |
MASK_NO_PUSH_ARGS |
Do not use push instructions to save outgoing arguments |
accumulate-outgoing-args |
MASK_ACCUMULATE_OUTGOING_ARGS |
Use push instructions to save outgoing arguments |
no-accumulate-outgoing-args |
-MASK_ACCUMULATE_OUTGOING_ARGS |
Do not use push instructions to save outgoing arguments |
mmx |
MASK_MMX |
Support MMX built-in functions |
no-mmx |
-MASK_MMX |
Do not support MMX built-in functions |
3dnow |
MASK_3DNOW |
Support 3DNow! built-in functions |
no-3dnow |
-MASK_3DNOW |
Do not support 3DNow! built-in functions |
sse |
MASK_SSE |
Support MMX and SSE built-in functions and code generation |
no-sse |
-MASK_SSE |
Do not support MMX and SSE built-in functions and code generation |
sse2 |
MASK_SSE2 |
Support MMX, SSE and SSE2 built-in functions and code generation |
no-sse2 |
-MASK_SSE2 |
Do not support MMX, SSE and SSE2 built-in functions and code generation |
sse3 |
MASK_SSE3 |
Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation |
no-sse3 |
-MASK_SSE3 |
Do not support MMX, SSE, SSE2 and SSE3 built-in functions and code generation |
128bit-long-double |
MASK_128BIT_LONG_DOUBLE |
sizeof(long double) is 16 |
96bit-long-double |
-MASK_128BIT_LONG_DOUBLE |
sizeof(long double) is 12 |
64 |
MASK_64BIT |
Generate 64bit x86-64 code |
32 |
-MASK_64BIT |
Generate 32bit i386 code |
ms-bitfields |
MASK_MS_BITFIELD_LAYOUT |
Use native (MS) bitfield layout |
no-ms-bitfields |
-MASK_MS_BITFIELD_LAYOUT |
Use gcc default bitfield layout |
red-zone |
-MASK_NO_RED_ZONE |
Use red-zone in the x86-64 code |
no-red-zone |
MASK_NO_RED_ZONE |
Do not use red-zone in the x86-64 code |
tls-direct-seg-refs |
MASK_TLS_DIRECT_SEG_REFS |
Use direct references against %gs when accessing tls data |
no-tls-direct-seg-refs |
-MASK_TLS_DIRECT_SEG_REFS |
Do not use direct references against %gs when accessing tls data |
Default options |
TARGET_DEFAULT | TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_DEFAULT| TARGET_TLS_DIRECT_SEG_REFS_DEFAULT |
Table 9: target_switches for i386 system
Above, at line 3839, target_flags contains bit flags that specify the machine subtype we are compiling for, and target_flags_explicit is a mask of target_flags that includes bit X if X was set or cleared on the command line.
While at line 3854, target_options is also target related switches which must be assigned with value. Its content is from TARGET_OPTIONS which is defined in i386.h.
1176 #ifdef TARGET_OPTIONS in toplev.c
1177 static const struct
1178 {
1179 const char *const prefix;
1180 const char **const variable;
1181 const char *const description;
1182 const char *const value;
1183 }
1184 target_options[] = TARGET_OPTIONS;
1185 #endif
Prefix
|
Variable |
Description |
Value |
tune= |
&ix86_tune_string |
Schedule code for given CPU |
0 |
fpmath= |
&ix86_fpmath_string |
Generate floating point mathematics using given instruction set |
0 |
arch= |
&ix86_arch_string |
Generate code for given CPU |
0 |
regparm= |
&ix86_regparm_string |
Number of registers used to pass integer arguments |
0 |
align-loops= [obsolete] |
&ix86_align_loops_string |
Loop code aligned to this power of 2 |
0 |
align-jumps=[obsolete] |
&ix86_align_jumps_string |
Jump targets are aligned to this power of 2 |
0 |
align-functions=[obsolete] |
&ix86_align_funcs_string |
Function starts are aligned to this power of 2 |
0 |
preferred-stack-boundary= |
x86_preferred_stack_boundary_string |
Attempt to keep stack aligned to this power of 2 |
0 |
branch-cost= |
&ix86_branch_cost_string |
Branches are this expensive (1-5, arbitrary units) |
0 |
cmodel= |
&ix86_cmodel_string |
Use given x86-64 code model |
0 |
debug-arg |
&ix86_debug_arg_string |
"" /* Undocumented. */ |
0 |
asm= |
&ix86_asm_string |
Use given assembler dialect |
0 |
tls-dialect= |
&ix86_tls_dialect_string |
Use given thread-local storage dialect |
0 |
Table 10: target_options for i386 system
Notice that value field in above table is always 0, in set_target_switch, at line 3865 always executed, and corresponding variable will be set.
In decode_options at line 605, when invoking set_target_switch, the parameter passed in is “” which equates to 0, thus gets the default values from TARGET_SWITCHES.
After setting down the default value for the options, at line 615, OPTIMIZATION_OPTIONS adjust the default value based upon specified platform. For x86 system, the macro and related function have following definitions.
512 #define OPTIMIZATION_OPTIONS(LEVEL, SIZE) / in i386.h
513 optimization_options ((LEVEL), (SIZE))
1502 void
1503 optimization_options (int level, int size ATTRIBUTE_UNUSED) in i386.c
1504 {
1505 /* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
1506 make the problem with not enough registers even worse. */
1507 #ifdef INSN_SCHEDULING
1508 if (level > 1)
1509 flag_schedule_insns = 0;
1510 #endif
1511
1512 /* The default values of these switches depend on the TARGET_64BIT
1513 that is not known at this moment. Mark these values with 2 and
1514 let user the to override these. In case there is no command line option
1515 specifying them, we will set the defaults in override_options. */
1516 if (optimize >= 1)
1517 flag_omit_frame_pointer = 2;
1518 flag_pcc_struct_return = 2;
1519 flag_asynchronous_unwind_tables = 2;
1520 }
Above, flag_schedule_insn and flag_omit_frame_pointer have been already encountered before. For the others, the details are as following.
flag_pcc_struct_return (-fpcc-struct-return), if nonzero, generates code to return all structures by storing them in memory even if they are small enough to fit in a register. The precise convention for returning structures in memory or in registers depends on the platform. While producing less efficient code, this option may be needed when linking to object files created using another compiler.
Also (-freg-struct-return), if nonzero, generates code to return short structures by storing them in registers. If they are not small enough to fit in a register, they are returned in memory. The precise convention for returning structures in memory or in registers depends on the platform.
flag_asynchronous_unwind_tables (-fasynchronous-unwind-tables), if nonzero, generates unwind table in DWARF2 format if supported on the target machine. The table is exact at each instruction boundary, so it can be used for stack unwinding from asynchronous events (such as debugger or garbage collector).