diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5ceb7b6b91a..d7455123d435 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2009-11-05 Paul Brook + + * config/arm/arm.c (arm_fp_model, arm_fpu_arch, arm_fpu_tune): Remove. + (arm_fpu_desc): New. + (all_fpus): Add FPU details. + (fp_model_for_fpu): Remove. + (arm_override_options): Set and use arm_fpu_desc and arm_fpu_attr. + (arm_output_epilogue, arm_save_coproc_regs): Use TARGET_FPA_EMU2. + (arm_file_start): Use arm_fpu_desc. + * config/arm/arm.h (TARGET_FPA, TARGET_MAVERICK, TARGET_VFP, + TARGET_VFPD32, TARGET_VFP3, TARGET_NEON_FP16, TARGET_NEON): Use + arm_fpu_desc. + (TARGET_FPA_EMU2): Define. + (arm_fp_model, fputype, arm_fpu_tune): Remove. + (vfp_reg_type, arm_fpu_desc): New. + * config/arm/arm.md (attr fpu): Simplify. + * config/arm/fpa.md (movxf_fpa): Use TARGET_FPA_EMU2. + * config/arm/linux-elf.h (FPUTYPE_DEFAULT): Use string value. + * config/arm/bpabi.h (FPUTYPE_DEFAULT): Use string value. + * config/arm/netbsd-elf.h (FPUTYPE_DEFAULT): Use string value. + * config/arm/vxworks.h (FPUTYPE_DEFAULT): Use string value. + 2009-11-05 Michael Matz * config/i386/i386.c (ix86_builtin_reciprocal): Remove dependency diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 25e433cd3a46..4c7fcb65854b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -524,14 +524,11 @@ enum processor_type arm_tune = arm_none; /* The default processor used if not overridden by commandline. */ static enum processor_type arm_default_cpu = arm_none; -/* Which floating point model to use. */ -enum arm_fp_model arm_fp_model; - -/* Which floating point hardware is available. */ -enum fputype arm_fpu_arch; - /* Which floating point hardware to schedule for. */ -enum fputype arm_fpu_tune; +int arm_fpu_attr; + +/* Which floating popint hardware to use. */ +const struct arm_fpu_desc *arm_fpu_desc; /* Whether to use floating point hardware. */ enum float_abi_type arm_float_abi; @@ -809,46 +806,21 @@ static struct arm_cpu_select arm_select[] = char arm_arch_name[] = "__ARM_ARCH_0UNK__"; -struct fpu_desc -{ - const char * name; - enum fputype fpu; -}; - - /* Available values for -mfpu=. */ -static const struct fpu_desc all_fpus[] = +static const struct arm_fpu_desc all_fpus[] = { - {"fpa", FPUTYPE_FPA}, - {"fpe2", FPUTYPE_FPA_EMU2}, - {"fpe3", FPUTYPE_FPA_EMU2}, - {"maverick", FPUTYPE_MAVERICK}, - {"vfp", FPUTYPE_VFP}, - {"vfp3", FPUTYPE_VFP3}, - {"vfpv3", FPUTYPE_VFP3}, - {"vfpv3-d16", FPUTYPE_VFP3D16}, - {"neon", FPUTYPE_NEON}, - {"neon-fp16", FPUTYPE_NEON_FP16} -}; - - -/* Floating point models used by the different hardware. - See fputype in arm.h. */ - -static const enum arm_fp_model fp_model_for_fpu[] = -{ - /* No FP hardware. */ - ARM_FP_MODEL_UNKNOWN, /* FPUTYPE_NONE */ - ARM_FP_MODEL_FPA, /* FPUTYPE_FPA */ - ARM_FP_MODEL_FPA, /* FPUTYPE_FPA_EMU2 */ - ARM_FP_MODEL_FPA, /* FPUTYPE_FPA_EMU3 */ - ARM_FP_MODEL_MAVERICK, /* FPUTYPE_MAVERICK */ - ARM_FP_MODEL_VFP, /* FPUTYPE_VFP */ - ARM_FP_MODEL_VFP, /* FPUTYPE_VFP3D16 */ - ARM_FP_MODEL_VFP, /* FPUTYPE_VFP3 */ - ARM_FP_MODEL_VFP, /* FPUTYPE_NEON */ - ARM_FP_MODEL_VFP /* FPUTYPE_NEON_FP16 */ + {"fpa", ARM_FP_MODEL_FPA, 0, 0, false, false}, + {"fpe2", ARM_FP_MODEL_FPA, 2, 0, false, false}, + {"fpe3", ARM_FP_MODEL_FPA, 3, 0, false, false}, + {"maverick", ARM_FP_MODEL_MAVERICK, 0, 0, false, false}, + {"vfp", ARM_FP_MODEL_VFP, 2, VFP_REG_D16, false, false}, + {"vfpv3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false}, + {"vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false}, + {"neon", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , false}, + {"neon-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, true , true }, + /* Compatibility aliases. */ + {"vfp3", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, false}, }; @@ -1615,7 +1587,6 @@ arm_override_options (void) 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")) @@ -1626,46 +1597,52 @@ arm_override_options (void) 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 + + if (target_fpu_name == NULL) { #ifdef FPUTYPE_DEFAULT - /* Use the default if it is specified for this platform. */ - arm_fpu_arch = FPUTYPE_DEFAULT; - arm_fpu_tune = FPUTYPE_DEFAULT; + target_fpu_name = 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; + target_fpu_name = "maverick"; else - arm_fpu_arch = FPUTYPE_FPA_EMU2; + target_fpu_name = "fpe2"; #endif - if (tune_flags & FL_CO_PROC && arm_fpu_arch == FPUTYPE_FPA_EMU2) - arm_fpu_tune = FPUTYPE_FPA; + } + + arm_fpu_desc = NULL; + for (i = 0; i < ARRAY_SIZE (all_fpus); i++) + { + if (streq (all_fpus[i].name, target_fpu_name)) + { + arm_fpu_desc = &all_fpus[i]; + break; + } + } + if (!arm_fpu_desc) + error ("invalid floating point option: -mfpu=%s", target_fpu_name); + + switch (arm_fpu_desc->model) + { + case ARM_FP_MODEL_FPA: + if (arm_fpu_desc->rev == 2) + arm_fpu_attr = FPU_FPE2; + else if (arm_fpu_desc->rev == 3) + arm_fpu_attr = FPU_FPE3; 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); + arm_fpu_attr = FPU_FPA; + break; + + case ARM_FP_MODEL_MAVERICK: + arm_fpu_attr = FPU_MAVERICK; + break; + + case ARM_FP_MODEL_VFP: + arm_fpu_attr = FPU_VFP; + break; + + default: + gcc_unreachable(); } if (target_float_abi_name != NULL) @@ -1687,7 +1664,7 @@ arm_override_options (void) arm_float_abi = TARGET_DEFAULT_FLOAT_ABI; if (TARGET_AAPCS_BASED - && (arm_fp_model == ARM_FP_MODEL_FPA)) + && (arm_fpu_desc->model == ARM_FP_MODEL_FPA)) error ("FPA is unsupported in the AAPCS"); if (TARGET_AAPCS_BASED) @@ -1715,7 +1692,7 @@ arm_override_options (void) /* If soft-float is specified then don't use FPU. */ if (TARGET_SOFT_FLOAT) - arm_fpu_arch = FPUTYPE_NONE; + arm_fpu_attr = FPU_NONE; if (TARGET_AAPCS_BASED) { @@ -1742,8 +1719,7 @@ arm_override_options (void) /* 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) + || (TARGET_FPA && arm_fpu_desc->rev)) && (tune_flags & FL_MODE32) == 0) flag_schedule_insns = flag_schedule_insns_after_reload = 0; @@ -13305,7 +13281,7 @@ arm_output_epilogue (rtx sibling) /* This variable is for the Virtual Frame Pointer, not VFP regs. */ int vfp_offset = offsets->frame; - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + if (TARGET_FPA_EMU2) { for (reg = LAST_FPA_REGNUM; reg >= FIRST_FPA_REGNUM; reg--) if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) @@ -13528,7 +13504,7 @@ arm_output_epilogue (rtx sibling) SP_REGNUM, HARD_FRAME_POINTER_REGNUM); } - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + if (TARGET_FPA_EMU2) { for (reg = FIRST_FPA_REGNUM; reg <= LAST_FPA_REGNUM; reg++) if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) @@ -14254,7 +14230,7 @@ arm_save_coproc_regs(void) /* Save any floating point call-saved registers used by this function. */ - if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + if (TARGET_FPA_EMU2) { for (reg = LAST_FPA_REGNUM; reg >= FIRST_FPA_REGNUM; reg--) if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) @@ -19736,45 +19712,8 @@ arm_file_start (void) } else { - int set_float_abi_attributes = 0; - switch (arm_fpu_arch) - { - case FPUTYPE_FPA: - fpu_name = "fpa"; - break; - case FPUTYPE_FPA_EMU2: - fpu_name = "fpe2"; - break; - case FPUTYPE_FPA_EMU3: - fpu_name = "fpe3"; - break; - case FPUTYPE_MAVERICK: - fpu_name = "maverick"; - break; - case FPUTYPE_VFP: - fpu_name = "vfp"; - set_float_abi_attributes = 1; - break; - case FPUTYPE_VFP3D16: - fpu_name = "vfpv3-d16"; - set_float_abi_attributes = 1; - break; - case FPUTYPE_VFP3: - fpu_name = "vfpv3"; - set_float_abi_attributes = 1; - break; - case FPUTYPE_NEON: - fpu_name = "neon"; - set_float_abi_attributes = 1; - break; - case FPUTYPE_NEON_FP16: - fpu_name = "neon-fp16"; - set_float_abi_attributes = 1; - break; - default: - abort(); - } - if (set_float_abi_attributes) + fpu_name = arm_fpu_desc->name; + if (arm_fpu_desc->model == ARM_FP_MODEL_VFP) { if (TARGET_HARD_FLOAT) asm_fprintf (asm_out_file, "\t.eabi_attribute 27, 3\n"); diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 9272ca51cbad..2dfd22df45c0 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -190,9 +190,9 @@ extern void (*arm_lang_output_object_attributes_hook)(void); #define TARGET_HARD_FLOAT (arm_float_abi != ARM_FLOAT_ABI_SOFT) /* Use hardware floating point calling convention. */ #define TARGET_HARD_FLOAT_ABI (arm_float_abi == ARM_FLOAT_ABI_HARD) -#define TARGET_FPA (arm_fp_model == ARM_FP_MODEL_FPA) -#define TARGET_MAVERICK (arm_fp_model == ARM_FP_MODEL_MAVERICK) -#define TARGET_VFP (arm_fp_model == ARM_FP_MODEL_VFP) +#define TARGET_FPA (arm_fpu_desc->model == ARM_FP_MODEL_FPA) +#define TARGET_MAVERICK (arm_fpu_desc->model == ARM_FP_MODEL_MAVERICK) +#define TARGET_VFP (arm_fpu_desc->model == ARM_FP_MODEL_VFP) #define TARGET_IWMMXT (arm_arch_iwmmxt) #define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_32BIT) #define TARGET_IWMMXT_ABI (TARGET_32BIT && arm_abi == ARM_ABI_IWMMXT) @@ -216,6 +216,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void); #define TARGET_THUMB2 (TARGET_THUMB && arm_arch_thumb2) /* Thumb-1 only. */ #define TARGET_THUMB1_ONLY (TARGET_THUMB1 && !arm_arch_notm) +/* FPA emulator without LFM. */ +#define TARGET_FPA_EMU2 (TARGET_FPA && arm_fpu_desc->rev == 2) /* The following two macros concern the ability to execute coprocessor instructions for VFPv3 or NEON. TARGET_VFP3/TARGET_VFPD32 are currently @@ -223,27 +225,21 @@ extern void (*arm_lang_output_object_attributes_hook)(void); to be more careful with TARGET_NEON as noted below. */ /* FPU is has the full VFPv3/NEON register file of 32 D registers. */ -#define TARGET_VFPD32 (arm_fp_model == ARM_FP_MODEL_VFP \ - && (arm_fpu_arch == FPUTYPE_VFP3 \ - || arm_fpu_arch == FPUTYPE_NEON \ - || arm_fpu_arch == FPUTYPE_NEON_FP16)) +#define TARGET_VFPD32 (TARGET_VFP && arm_fpu_desc->regs == VFP_REG_D32) /* FPU supports VFPv3 instructions. */ -#define TARGET_VFP3 (arm_fp_model == ARM_FP_MODEL_VFP \ - && (arm_fpu_arch == FPUTYPE_VFP3D16 \ - || TARGET_VFPD32)) +#define TARGET_VFP3 (TARGET_VFP && arm_fpu_desc->rev >= 3) /* FPU supports NEON/VFP half-precision floating-point. */ -#define TARGET_NEON_FP16 (arm_fpu_arch == FPUTYPE_NEON_FP16) +#define TARGET_NEON_FP16 \ + (TARGET_VFP && arm_fpu_desc->neon && arm_fpu_desc->fp16) /* FPU supports Neon instructions. The setting of this macro gets revealed via __ARM_NEON__ so we add extra guards upon TARGET_32BIT and TARGET_HARD_FLOAT to ensure that NEON instructions are available. */ #define TARGET_NEON (TARGET_32BIT && TARGET_HARD_FLOAT \ - && arm_fp_model == ARM_FP_MODEL_VFP \ - && (arm_fpu_arch == FPUTYPE_NEON \ - || arm_fpu_arch == FPUTYPE_NEON_FP16)) + && TARGET_VFP && arm_fpu_desc->neon) /* "DSP" multiply instructions, eg. SMULxy. */ #define TARGET_DSP_MULTIPLY \ @@ -300,42 +296,25 @@ enum arm_fp_model ARM_FP_MODEL_VFP }; -extern enum arm_fp_model arm_fp_model; - -/* Which floating point hardware is available. Also update - fp_model_for_fpu in arm.c when adding entries to this list. */ -enum fputype +enum vfp_reg_type { - /* No FP hardware. */ - FPUTYPE_NONE, - /* Full FPA support. */ - FPUTYPE_FPA, - /* Emulated FPA hardware, Issue 2 emulator (no LFM/SFM). */ - FPUTYPE_FPA_EMU2, - /* Emulated FPA hardware, Issue 3 emulator. */ - FPUTYPE_FPA_EMU3, - /* Cirrus Maverick floating point co-processor. */ - FPUTYPE_MAVERICK, - /* VFP. */ - FPUTYPE_VFP, - /* VFPv3-D16. */ - FPUTYPE_VFP3D16, - /* VFPv3. */ - FPUTYPE_VFP3, - /* Neon. */ - FPUTYPE_NEON, - /* Neon with half-precision float extensions. */ - FPUTYPE_NEON_FP16 + VFP_REG_D16, + VFP_REG_D32, + VFP_REG_SINGLE }; -/* Recast the floating point class to be the floating point attribute. */ -#define arm_fpu_attr ((enum attr_fpu) arm_fpu_tune) +extern const struct arm_fpu_desc +{ + const char *name; + enum arm_fp_model model; + int rev; + enum vfp_reg_type regs; + int neon; + int fp16; +} *arm_fpu_desc; -/* What type of floating point to tune for */ -extern enum fputype arm_fpu_tune; - -/* What type of floating point instructions are available */ -extern enum fputype arm_fpu_arch; +/* Which floating point hardware to schedule for. */ +extern int arm_fpu_attr; enum float_abi_type { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index fbc52f4600f8..52edcbaa17b3 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -160,7 +160,7 @@ ; Floating Point Unit. If we only have floating point emulation, then there ; is no point in scheduling the floating point insns. (Well, for best ; performance we should try and group them together). -(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp,vfpv3d16,vfpv3,neon,neon_fp16" +(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp" (const (symbol_ref "arm_fpu_attr"))) ; LENGTH of an instruction (in bytes) diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h index 8d3afbf55fdb..ba206022b750 100644 --- a/gcc/config/arm/bpabi.h +++ b/gcc/config/arm/bpabi.h @@ -30,7 +30,7 @@ /* Section 4.1 of the AAPCS requires the use of VFP format. */ #undef FPUTYPE_DEFAULT -#define FPUTYPE_DEFAULT FPUTYPE_VFP +#define FPUTYPE_DEFAULT "vfp" /* TARGET_BIG_ENDIAN_DEFAULT is set in config.gcc for big endian configurations. */ diff --git a/gcc/config/arm/fpa.md b/gcc/config/arm/fpa.md index fcd92b002d7b..515de43d28bd 100644 --- a/gcc/config/arm/fpa.md +++ b/gcc/config/arm/fpa.md @@ -599,10 +599,10 @@ { default: case 0: return \"mvf%?e\\t%0, %1\"; - case 1: if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + case 1: if (TARGET_FPA_EMU2) return \"ldf%?e\\t%0, %1\"; return \"lfm%?\\t%0, 1, %1\"; - case 2: if (arm_fpu_arch == FPUTYPE_FPA_EMU2) + case 2: if (TARGET_FPA_EMU2) return \"stf%?e\\t%1, %0\"; return \"sfm%?\\t%1, 1, %0\"; } diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h index 07455ee87fd6..9fdca414e8ef 100644 --- a/gcc/config/arm/linux-elf.h +++ b/gcc/config/arm/linux-elf.h @@ -98,7 +98,7 @@ /* NWFPE always understands FPA instructions. */ #undef FPUTYPE_DEFAULT -#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU3 +#define FPUTYPE_DEFAULT "fpe3" /* Call the function profiler with a given profile label. */ #undef ARM_FUNCTION_PROFILER diff --git a/gcc/config/arm/netbsd-elf.h b/gcc/config/arm/netbsd-elf.h index 4c06fa1cb3b4..9cf186b338d3 100644 --- a/gcc/config/arm/netbsd-elf.h +++ b/gcc/config/arm/netbsd-elf.h @@ -153,5 +153,5 @@ do \ while (0) #undef FPUTYPE_DEFAULT -#define FPUTYPE_DEFAULT FPUTYPE_VFP +#define FPUTYPE_DEFAULT "vfp" diff --git a/gcc/config/arm/vxworks.h b/gcc/config/arm/vxworks.h index 8879fedb7d79..aa7e197bc5df 100644 --- a/gcc/config/arm/vxworks.h +++ b/gcc/config/arm/vxworks.h @@ -97,7 +97,7 @@ along with GCC; see the file COPYING3. If not see /* There is no default multilib. */ #undef MULTILIB_DEFAULTS -#define FPUTYPE_DEFAULT FPUTYPE_VFP +#define FPUTYPE_DEFAULT "vfp" #undef FUNCTION_PROFILER #define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER