📄 arm.c
字号:
set_optab_libfunc (umod_optab, SImode, NULL);}/* Implement TARGET_HANDLE_OPTION. */static boolarm_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED){ switch (code) { case OPT_march_: arm_select[1].string = arg; return true; case OPT_mcpu_: arm_select[0].string = arg; return true; case OPT_mhard_float: target_float_abi_name = "hard"; return true; case OPT_msoft_float: target_float_abi_name = "soft"; return true; case OPT_mtune_: arm_select[2].string = arg; return true; default: return true; }}/* Fix up any incompatible options that the user has specified. This has now turned into a maze. */voidarm_override_options (void){ unsigned i; enum processor_type target_arch_cpu = arm_none; /* Set up the flags based on the cpu/architecture selected by the user. */ for (i = ARRAY_SIZE (arm_select); i--;) { 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_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 (sel->name == NULL) error ("bad value (%s) for %s switch", ptr->string, ptr->name); } } /* 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) { const struct processors * sel; unsigned int sought; enum processor_type cpu; cpu = TARGET_CPU_DEFAULT; if (cpu == arm_none) {#ifdef SUBTARGET_CPU_DEFAULT /* Use the subtarget default CPU if none was specified by configure. */ cpu = SUBTARGET_CPU_DEFAULT;#endif /* Default to ARM6. */ if (cpu == arm_none) cpu = arm6; } sel = &all_cores[cpu]; insn_flags = sel->flags; /* Now check to see if the user has specified some command line switch that require certain abilities from the cpu. */ sought = 0; if (TARGET_INTERWORK || TARGET_THUMB) { sought |= (FL_THUMB | FL_MODE32); /* There are no ARM processors that support both APCS-26 and interworking. Therefore we force FL_MODE26 to be removed from insn_flags here (if it was set), so that the search below will always be able to find a compatible processor. */ insn_flags &= ~FL_MODE26; } if (sought != 0 && ((sought & insn_flags) != sought)) { /* Try to locate a CPU type that supports all of the abilities of the default CPU, plus the extra abilities requested by the user. */ for (sel = all_cores; sel->name != NULL; sel++) if ((sel->flags & sought) == (sought | insn_flags)) break; if (sel->name == NULL) { unsigned current_bit_count = 0; const struct processors * best_fit = NULL; /* Ideally we would like to issue an error message here saying that it was not possible to find a CPU compatible with the default CPU, but which also supports the command line options specified by the programmer, and so they ought to use the -mcpu=<name> command line option to override the default CPU type. If we cannot find a cpu that has both the characteristics of the default cpu and the given command line options we scan the array again looking for a best match. */ for (sel = all_cores; sel->name != NULL; sel++) if ((sel->flags & sought) == sought) { unsigned count; count = bit_count (sel->flags & insn_flags); if (count >= current_bit_count) { best_fit = sel; current_bit_count = count; } } gcc_assert (best_fit); sel = best_fit; } insn_flags = sel->flags; } sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch); if (arm_tune == arm_none) arm_tune = (enum processor_type) (sel - all_cores); } /* The processor for which we should tune should now have been chosen. */ gcc_assert (arm_tune != arm_none); tune_flags = all_cores[(int)arm_tune].flags; if (optimize_size) targetm.rtx_costs = arm_size_rtx_costs; else targetm.rtx_costs = all_cores[(int)arm_tune].rtx_costs; /* Make sure that the processor choice does not conflict with any of the other command line choices. */ if (TARGET_INTERWORK && !(insn_flags & FL_THUMB)) { warning (0, "target CPU does not support interworking" ); target_flags &= ~MASK_INTERWORK; } if (TARGET_THUMB && !(insn_flags & FL_THUMB)) { warning (0, "target CPU does not support THUMB instructions"); target_flags &= ~MASK_THUMB; } if (TARGET_APCS_FRAME && TARGET_THUMB) { /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */ target_flags &= ~MASK_APCS_FRAME; } /* Callee super interworking implies thumb interworking. Adding this to the flags here simplifies the logic elsewhere. */ if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING) target_flags |= MASK_INTERWORK; /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done from here where no function is being compiled currently. */ if ((TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) && TARGET_ARM) warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb"); if (TARGET_ARM && TARGET_CALLEE_INTERWORKING) warning (0, "enabling callee interworking support is only meaningful when compiling for the Thumb"); if (TARGET_ARM && TARGET_CALLER_INTERWORKING) warning (0, "enabling caller interworking support is only meaningful when compiling for the Thumb"); if (TARGET_APCS_STACK && !TARGET_APCS_FRAME) { warning (0, "-mapcs-stack-check incompatible with -mno-apcs-frame"); target_flags |= MASK_APCS_FRAME; } if (TARGET_POKE_FUNCTION_NAME) target_flags |= MASK_APCS_FRAME; if (TARGET_APCS_REENT && flag_pic) error ("-fpic and -mapcs-reent are incompatible"); if (TARGET_APCS_REENT) warning (0, "APCS reentrant code not supported. Ignored"); /* If this target is normally configured to use APCS frames, warn if they are turned off and debugging is turned on. */ if (TARGET_ARM && write_symbols != NO_DEBUG && !TARGET_APCS_FRAME && (TARGET_DEFAULT & MASK_APCS_FRAME)) warning (0, "-g with -mno-apcs-frame may not give sensible debugging"); /* If stack checking is disabled, we can use r10 as the PIC register, which keeps r9 available. */ if (flag_pic) arm_pic_register = TARGET_APCS_STACK ? 9 : 10; if (TARGET_APCS_FLOAT) warning (0, "passing floating point arguments in fp regs not yet supported"); /* Initialize boolean versions of the flags, for use in the arm.md file. */ arm_arch3m = (insn_flags & FL_ARCH3M) != 0; arm_arch4 = (insn_flags & FL_ARCH4) != 0; arm_arch4t = arm_arch4 & ((insn_flags & FL_THUMB) != 0); arm_arch5 = (insn_flags & FL_ARCH5) != 0; arm_arch5e = (insn_flags & FL_ARCH5E) != 0; arm_arch6 = (insn_flags & FL_ARCH6) != 0; arm_arch6k = (insn_flags & FL_ARCH6K) != 0; arm_arch_xscale = (insn_flags & FL_XSCALE) != 0; arm_arch_cirrus = (insn_flags & FL_CIRRUS) != 0; arm_ld_sched = (tune_flags & FL_LDSCHED) != 0; arm_tune_strongarm = (tune_flags & FL_STRONG) != 0; thumb_code = (TARGET_ARM == 0); arm_tune_wbuf = (tune_flags & FL_WBUF) != 0; arm_tune_xscale = (tune_flags & FL_XSCALE) != 0; arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0; /* V5 code we generate is completely interworking capable, so we turn off TARGET_INTERWORK here to avoid many tests later on. */ /* XXX However, we must pass the right pre-processor defines to CPP or GLD can get confused. This is a hack. */ if (TARGET_INTERWORK) arm_cpp_interwork = 1; if (arm_arch5) target_flags &= ~MASK_INTERWORK; if (target_abi_name) { for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++) { if (streq (arm_all_abis[i].name, target_abi_name)) { arm_abi = arm_all_abis[i].abi_type; break; } } if (i == ARRAY_SIZE (arm_all_abis)) error ("invalid ABI option: -mabi=%s", target_abi_name); } else arm_abi = ARM_DEFAULT_ABI; if (TARGET_IWMMXT && !ARM_DOUBLEWORD_ALIGN) error ("iwmmxt requires an AAPCS compatible ABI for proper operation"); if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT) error ("iwmmxt abi requires an iwmmxt capable cpu"); arm_fp_model = ARM_FP_MODEL_UNKNOWN; if (target_fpu_name == NULL && target_fpe_name != NULL) { if (streq (target_fpe_name, "2")) target_fpu_name = "fpe2"; else if (streq (target_fpe_name, "3")) target_fpu_name = "fpe3"; else error ("invalid floating point emulation option: -mfpe=%s", target_fpe_name); } if (target_fpu_name != NULL) { /* The user specified a FPU. */ for (i = 0; i < ARRAY_SIZE (all_fpus); i++) { if (streq (all_fpus[i].name, target_fpu_name)) { arm_fpu_arch = all_fpus[i].fpu; arm_fpu_tune = arm_fpu_arch; arm_fp_model = fp_model_for_fpu[arm_fpu_arch]; break; } } if (arm_fp_model == ARM_FP_MODEL_UNKNOWN) error ("invalid floating point option: -mfpu=%s", target_fpu_name); } else {#ifdef FPUTYPE_DEFAULT /* Use the default if it is specified for this platform. */ arm_fpu_arch = FPUTYPE_DEFAULT; arm_fpu_tune = FPUTYPE_DEFAULT;#else /* Pick one based on CPU type. */ /* ??? Some targets assume FPA is the default. if ((insn_flags & FL_VFP) != 0) arm_fpu_arch = FPUTYPE_VFP; else */ if (arm_arch_cirrus) arm_fpu_arch = FPUTYPE_MAVERICK; else arm_fpu_arch = FPUTYPE_FPA_EMU2;#endif if (tune_flags & FL_CO_PROC && arm_fpu_arch == FPUTYPE_FPA_EMU2) arm_fpu_tune = FPUTYPE_FPA; else arm_fpu_tune = arm_fpu_arch; arm_fp_model = fp_model_for_fpu[arm_fpu_arch]; gcc_assert (arm_fp_model != ARM_FP_MODEL_UNKNOWN); } if (target_float_abi_name != NULL) { /* The user specified a FP ABI. */ for (i = 0; i < ARRAY_SIZE (all_float_abis); i++) { if (streq (all_float_abis[i].name, target_float_abi_name)) { arm_float_abi = all_float_abis[i].abi_type; break; } } if (i == ARRAY_SIZE (all_float_abis)) error ("invalid floating point abi: -mfloat-abi=%s", target_float_abi_name); } else arm_float_abi = TARGET_DEFAULT_FLOAT_ABI; if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP) sorry ("-mfloat-abi=hard and VFP"); /* If soft-float is specified then don't use FPU. */ if (TARGET_SOFT_FLOAT) arm_fpu_arch = FPUTYPE_NONE; /* For arm2/3 there is no need to do any scheduling if there is only a floating point emulator, or we are doing software floating-point. */ if ((TARGET_SOFT_FLOAT || arm_fpu_tune == FPUTYPE_FPA_EMU2 || arm_fpu_tune == FPUTYPE_FPA_EMU3) && (tune_flags & FL_MODE32) == 0) flag_schedule_insns = flag_schedule_insns_after_reload = 0; if (target_thread_switch) { if (strcmp (target_thread_switch, "soft") == 0) target_thread_pointer = TP_SOFT; else if (strcmp (target_thread_switch, "auto") == 0) target_thread_pointer = TP_AUTO; else if (strcmp (target_thread_switch, "cp15") == 0) target_thread_pointer = TP_CP15; else error ("invalid thread pointer option: -mtp=%s", target_thread_switch); } /* Use the cp15 method if it is available. */ if (target_thread_pointer == TP_AUTO)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -