2010-10-09 Jie Zhang Backport from mainline: gcc/ 2010-06-03 Paul Brook * config/arm/arm.c (FL_TUNE): Define. (arm_default_cpu, arm_cpu_select): Remove. (all_cores): Populate core field. (arm_selected_arch, arm_selected_cpu, arm_selected_tune): New. (arm_find_cpu): New function. (arm_handle_option): Lookup cpu/architecture names. (arm_override_options): Cleanup mcpu/march/mtune handling. (arm_file_start): Ditto. === modified file 'gcc/config/arm/arm.c' Index: gcc-4.5/gcc/config/arm/arm.c =================================================================== --- gcc-4.5.orig/gcc/config/arm/arm.c +++ gcc-4.5/gcc/config/arm/arm.c @@ -550,9 +550,6 @@ enum processor_type arm_tune = arm_none; /* The current tuning set. */ const struct tune_params *current_tune; -/* The default processor used if not overridden by commandline. */ -static enum processor_type arm_default_cpu = arm_none; - /* Which floating point hardware to schedule for. */ int arm_fpu_attr; @@ -608,6 +605,10 @@ static int thumb_call_reg_needed; #define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */ +/* Flags that only effect tuning, not available instructions. */ +#define FL_TUNE (FL_WBUF | FL_VFPV2 | FL_STRONG | FL_LDSCHED \ + | FL_CO_PROC) + #define FL_FOR_ARCH2 FL_NOTM #define FL_FOR_ARCH3 (FL_FOR_ARCH2 | FL_MODE32) #define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M) @@ -808,7 +809,7 @@ static const struct processors all_cores { /* ARM Cores */ #define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \ - {NAME, arm_none, #ARCH, FLAGS | FL_FOR_ARCH##ARCH, &arm_##COSTS##_tune}, + {NAME, IDENT, #ARCH, FLAGS | FL_FOR_ARCH##ARCH, &arm_##COSTS##_tune}, #include "arm-cores.def" #undef ARM_CORE {NULL, arm_none, NULL, 0, NULL} @@ -850,29 +851,12 @@ static const struct processors all_archi {NULL, arm_none, NULL, 0 , NULL} }; -struct arm_cpu_select -{ - const char * string; - const char * name; - const struct processors * processors; -}; - -/* This is a magic structure. The 'string' field is magically filled in - with a pointer to the value specified by the user on the command line - assuming that the user has specified such a value. */ - -static struct arm_cpu_select arm_select[] = -{ - /* string name processors */ - { NULL, "-mcpu=", all_cores }, - { NULL, "-march=", all_architectures }, - { NULL, "-mtune=", all_cores } -}; -/* Defines representing the indexes into the above table. */ -#define ARM_OPT_SET_CPU 0 -#define ARM_OPT_SET_ARCH 1 -#define ARM_OPT_SET_TUNE 2 +/* These are populated as commandline arguments are processed, or NULL + if not specified. */ +static const struct processors *arm_selected_arch; +static const struct processors *arm_selected_cpu; +static const struct processors *arm_selected_tune; /* The name of the preprocessor macro to define for this architecture. */ @@ -1234,6 +1218,24 @@ arm_gimplify_va_arg_expr (tree valist, t return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); } +/* Lookup NAME in SEL. */ + +static const struct processors * +arm_find_cpu (const char *name, const struct processors *sel, const char *desc) +{ + if (!(name && *name)) + return NULL; + + for (; sel->name != NULL; sel++) + { + if (streq (name, sel->name)) + return sel; + } + + error ("bad value (%s) for %s switch", name, desc); + return NULL; +} + /* Implement TARGET_HANDLE_OPTION. */ static bool @@ -1242,11 +1244,11 @@ arm_handle_option (size_t code, const ch switch (code) { case OPT_march_: - arm_select[1].string = arg; + arm_selected_arch = arm_find_cpu(arg, all_architectures, "-march"); return true; case OPT_mcpu_: - arm_select[0].string = arg; + arm_selected_cpu = arm_find_cpu(arg, all_cores, "-mcpu"); return true; case OPT_mhard_float: @@ -1258,7 +1260,7 @@ arm_handle_option (size_t code, const ch return true; case OPT_mtune_: - arm_select[2].string = arg; + arm_selected_tune = arm_find_cpu(arg, all_cores, "-mtune"); return true; default: @@ -1358,88 +1360,52 @@ void arm_override_options (void) { unsigned i; - enum processor_type target_arch_cpu = arm_none; - enum processor_type selected_cpu = arm_none; - /* Set up the flags based on the cpu/architecture selected by the user. */ - for (i = ARRAY_SIZE (arm_select); i--;) + if (arm_selected_arch) { - struct arm_cpu_select * ptr = arm_select + i; - - if (ptr->string != NULL && ptr->string[0] != '\0') - { - const struct processors * sel; - - for (sel = ptr->processors; sel->name != NULL; sel++) - if (streq (ptr->string, sel->name)) - { - /* Set the architecture define. */ - if (i != ARM_OPT_SET_TUNE) - sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch); - - /* Determine the processor core for which we should - tune code-generation. */ - if (/* -mcpu= is a sensible default. */ - i == ARM_OPT_SET_CPU - /* -mtune= overrides -mcpu= and -march=. */ - || i == ARM_OPT_SET_TUNE) - arm_tune = (enum processor_type) (sel - ptr->processors); - - /* Remember the CPU associated with this architecture. - If no other option is used to set the CPU type, - we'll use this to guess the most suitable tuning - options. */ - if (i == ARM_OPT_SET_ARCH) - target_arch_cpu = sel->core; - - if (i == ARM_OPT_SET_CPU) - selected_cpu = (enum processor_type) (sel - ptr->processors); - - if (i != ARM_OPT_SET_TUNE) - { - /* If we have been given an architecture and a processor - make sure that they are compatible. We only generate - a warning though, and we prefer the CPU over the - architecture. */ - if (insn_flags != 0 && (insn_flags ^ sel->flags)) - warning (0, "switch -mcpu=%s conflicts with -march= switch", - ptr->string); - - insn_flags = sel->flags; - } - - break; - } + if (arm_selected_cpu) + { + /* Check for conflict between mcpu and march */ + if ((arm_selected_cpu->flags ^ arm_selected_arch->flags) & ~FL_TUNE) + { + warning (0, "switch -mcpu=%s conflicts with -march=%s switch", + arm_selected_cpu->name, arm_selected_arch->name); + /* -march wins for code generation. + -mcpu wins for default tuning. */ + if (!arm_selected_tune) + arm_selected_tune = arm_selected_cpu; - if (sel->name == NULL) - error ("bad value (%s) for %s switch", ptr->string, ptr->name); - } + arm_selected_cpu = arm_selected_arch; + } + else + /* -mcpu wins. */ + arm_selected_arch = NULL; + } + else + /* Pick a CPU based on the architecture. */ + arm_selected_cpu = arm_selected_arch; } - /* Guess the tuning options from the architecture if necessary. */ - if (arm_tune == arm_none) - arm_tune = target_arch_cpu; - /* If the user did not specify a processor, choose one for them. */ - if (insn_flags == 0) + if (!arm_selected_cpu) { const struct processors * sel; unsigned int sought; - selected_cpu = (enum processor_type) TARGET_CPU_DEFAULT; - if (selected_cpu == arm_none) + arm_selected_cpu = &all_cores[TARGET_CPU_DEFAULT]; + if (!arm_selected_cpu->name) { #ifdef SUBTARGET_CPU_DEFAULT /* Use the subtarget default CPU if none was specified by configure. */ - selected_cpu = (enum processor_type) SUBTARGET_CPU_DEFAULT; + arm_selected_cpu = &all_cores[SUBTARGET_CPU_DEFAULT]; #endif /* Default to ARM6. */ - if (selected_cpu == arm_none) - selected_cpu = arm6; + if (arm_selected_cpu->name) + arm_selected_cpu = &all_cores[arm6]; } - sel = &all_cores[selected_cpu]; + sel = arm_selected_cpu; insn_flags = sel->flags; /* Now check to see if the user has specified some command line @@ -1500,17 +1466,21 @@ arm_override_options (void) sel = best_fit; } - insn_flags = sel->flags; + arm_selected_cpu = sel; } - sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch); - arm_default_cpu = (enum processor_type) (sel - all_cores); - if (arm_tune == arm_none) - arm_tune = arm_default_cpu; } - /* The processor for which we should tune should now have been - chosen. */ - gcc_assert (arm_tune != arm_none); + gcc_assert (arm_selected_cpu); + /* The selected cpu may be an architecture, so lookup tuning by core ID. */ + if (!arm_selected_tune) + arm_selected_tune = &all_cores[arm_selected_cpu->core]; + + sprintf (arm_arch_name, "__ARM_ARCH_%s__", arm_selected_cpu->arch); + insn_flags = arm_selected_cpu->flags; + + arm_tune = arm_selected_tune->core; + tune_flags = arm_selected_tune->flags; + current_tune = arm_selected_tune->tune; if (arm_tune == cortexa8 && optimize >= 3) { @@ -1522,9 +1492,6 @@ arm_override_options (void) align_jumps = 16; } - tune_flags = all_cores[(int)arm_tune].flags; - current_tune = all_cores[(int)arm_tune].tune; - if (target_fp16_format_name) { for (i = 0; i < ARRAY_SIZE (all_fp16_formats); i++) @@ -1907,7 +1874,7 @@ arm_override_options (void) /* Enable -mfix-cortex-m3-ldrd by default for Cortex-M3 cores. */ if (fix_cm3_ldrd == 2) { - if (selected_cpu == cortexm3) + if (arm_selected_cpu->core == cortexm3) fix_cm3_ldrd = 1; else fix_cm3_ldrd = 0; @@ -21235,13 +21202,10 @@ arm_file_start (void) if (TARGET_BPABI) { const char *fpu_name; - if (arm_select[0].string) - asm_fprintf (asm_out_file, "\t.cpu %s\n", arm_select[0].string); - else if (arm_select[1].string) - asm_fprintf (asm_out_file, "\t.arch %s\n", arm_select[1].string); + if (arm_selected_arch) + asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name); else - asm_fprintf (asm_out_file, "\t.cpu %s\n", - all_cores[arm_default_cpu].name); + asm_fprintf (asm_out_file, "\t.cpu %s\n", arm_selected_cpu->name); if (TARGET_SOFT_FLOAT) {