From: pbrook Date: Mon, 9 Nov 2009 13:50:38 +0000 (+0000) Subject: 2009-11-09 Paul Brook X-Git-Tag: upstream/4.9.2~32686 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a50d72676fd0ab3443fb73e4f1535713d2d781df;p=platform%2Fupstream%2Flinaro-gcc.git 2009-11-09 Paul Brook Daniel Jacobowitz Sandra Loosemore gcc/ * doc/extend.texi (Half-Precision): Update wording to reflect that there are now multiple -mfpu options that enable fp16 hardware support. * doc/invoke.texi: Update list of ARM -mfpu= options. * config.gcc: Update ARM --with-fpu option list. * config/arm/arm.c (all_fpus): Add vfpv3-fp16, vfpv3-d16-fp16, vfpv3xd and vfpv3xd-fp16. (use_vfp_abi): New function. (aapcs_vfp_is_call_or_return_candidate): Avoid double precision regs when undesirable. (aapcs_vfp_is_return_candidate, aapcs_vfp_is_call_candidate, aapcs_vfp_allocate_return_reg): Use use_vfp_abi. (arm_rtx_costs_1, arm_size_rtx_costs, arm_fastmul_rtx_costs, arm_9e_rtx_costs): Only expect double-precision operations if the FPU provides them. (coproc_secondary_reload_class): Reload HFmode via GENERAL_REGS if no NEON. (arm_print_operand): Handle 'p' modifier. (arm_hard_regno_mode_ok): : Allow HFmode in VFP registers if TARGET_FP16. * config/arm/arm.h (TARGET_VFP_SINGLE, TARGET_VFP_DOUBLE): Define. (TARGET_FP16): Define. * config/arm/vfp.md: Disable double-precision patterns if the FPU does not provide them. (arm_movdi_vfp, thumb2_movdi_vfp): Use fcpys to move double-precision values on a single-precision FPU. (movdf_vfp, thumb2_movdf_vfp): Likewise. Use "Dy" for double-precision constants. (movhf_vfp_neon): New pattern (was movhf_vfp). (movhf_vfp): Remove NEON instructions. * config/arm/constraints.md: Add new "Dy" constraint for double-precision constants. Update description of "Dv". * config/arm/arm.md: Disable double-precision patterns if the FPU does not provide them git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154034 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8301826..b6d48d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,42 @@ +2009-11-09 Paul Brook + Daniel Jacobowitz + Sandra Loosemore + + * doc/extend.texi (Half-Precision): Update wording to reflect + that there are now multiple -mfpu options that enable fp16 + hardware support. + * doc/invoke.texi: Update list of ARM -mfpu= options. + * config.gcc: Update ARM --with-fpu option list. + * config/arm/arm.c (all_fpus): Add vfpv3-fp16, vfpv3-d16-fp16, + vfpv3xd and vfpv3xd-fp16. + (use_vfp_abi): New function. + (aapcs_vfp_is_call_or_return_candidate): Avoid double precision regs + when undesirable. + (aapcs_vfp_is_return_candidate, aapcs_vfp_is_call_candidate, + aapcs_vfp_allocate_return_reg): Use use_vfp_abi. + (arm_rtx_costs_1, arm_size_rtx_costs, arm_fastmul_rtx_costs, + arm_9e_rtx_costs): Only expect double-precision operations if the FPU + provides them. + (coproc_secondary_reload_class): Reload HFmode via GENERAL_REGS if no + NEON. + (arm_print_operand): Handle 'p' modifier. + (arm_hard_regno_mode_ok): : Allow HFmode in VFP registers if + TARGET_FP16. + * config/arm/arm.h (TARGET_VFP_SINGLE, TARGET_VFP_DOUBLE): Define. + (TARGET_FP16): Define. + * config/arm/vfp.md: Disable double-precision patterns if the FPU + does not provide them. + (arm_movdi_vfp, thumb2_movdi_vfp): Use fcpys to move + double-precision values on a single-precision FPU. + (movdf_vfp, thumb2_movdf_vfp): Likewise. Use "Dy" for + double-precision constants. + (movhf_vfp_neon): New pattern (was movhf_vfp). + (movhf_vfp): Remove NEON instructions. + * config/arm/constraints.md: Add new "Dy" constraint for + double-precision constants. Update description of "Dv". + * config/arm/arm.md: Disable double-precision patterns if the FPU + does not provide them + 2009-11-09 Jakub Jelinek * config/i386/i386.c (print_operand) : Fix formatting. diff --git a/gcc/config.gcc b/gcc/config.gcc index 1d3c3fc..999ba21 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2817,7 +2817,7 @@ case "${target}" in case "$with_fpu" in "" \ - | fpa | fpe2 | fpe3 | maverick | vfp | vfp3 | neon ) + | fpa | fpe2 | fpe3 | maverick | vfp | vfp3 | vfpv3 | vfpv3-fp16 | vfpv3-d16 | vfpv3-d16-fp16 | vfpv3xd | vfpv3xd-fp16 | neon | neon-fp16 ) # OK ;; *) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 4c7fcb6..205bff2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -816,7 +816,11 @@ static const struct arm_fpu_desc all_fpus[] = {"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-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D32, false, true}, {"vfpv3-d16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, false}, + {"vfpv3-d16-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_D16, false, true}, + {"vfpv3xd", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, false}, + {"vfpv3xd-fp16", ARM_FP_MODEL_VFP, 3, VFP_REG_SINGLE, false, true}, {"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. */ @@ -3817,38 +3821,57 @@ aapcs_vfp_sub_candidate (const_tree type, enum machine_mode *modep) return -1; } +/* Return true if PCS_VARIANT should use VFP registers. */ static bool -aapcs_vfp_is_call_or_return_candidate (enum machine_mode mode, const_tree type, - enum machine_mode *base_mode, - int *count) +use_vfp_abi (enum arm_pcs pcs_variant, bool is_double) { + if (pcs_variant == ARM_PCS_AAPCS_VFP) + return true; + + if (pcs_variant != ARM_PCS_AAPCS_LOCAL) + return false; + + return (TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT && + (TARGET_VFP_DOUBLE || !is_double)); +} + +static bool +aapcs_vfp_is_call_or_return_candidate (enum arm_pcs pcs_variant, + enum machine_mode mode, const_tree type, + int *base_mode, int *count) +{ + enum machine_mode new_mode = VOIDmode; + if (GET_MODE_CLASS (mode) == MODE_FLOAT || GET_MODE_CLASS (mode) == MODE_VECTOR_INT || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) { *count = 1; - *base_mode = mode; - return true; + new_mode = mode; } else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) { *count = 2; - *base_mode = (mode == DCmode ? DFmode : SFmode); - return true; + new_mode = (mode == DCmode ? DFmode : SFmode); } else if (type && (mode == BLKmode || TREE_CODE (type) == VECTOR_TYPE)) { - enum machine_mode aggregate_mode = VOIDmode; - int ag_count = aapcs_vfp_sub_candidate (type, &aggregate_mode); + int ag_count = aapcs_vfp_sub_candidate (type, &new_mode); if (ag_count > 0 && ag_count <= 4) - { - *count = ag_count; - *base_mode = aggregate_mode; - return true; - } + *count = ag_count; + else + return false; } - return false; + else + return false; + + + if (!use_vfp_abi (pcs_variant, ARM_NUM_REGS (new_mode) > 1)) + return false; + + *base_mode = new_mode; + return true; } static bool @@ -3858,22 +3881,20 @@ aapcs_vfp_is_return_candidate (enum arm_pcs pcs_variant, int count ATTRIBUTE_UNUSED; enum machine_mode ag_mode ATTRIBUTE_UNUSED; - if (!(pcs_variant == ARM_PCS_AAPCS_VFP - || (pcs_variant == ARM_PCS_AAPCS_LOCAL - && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT))) + if (!use_vfp_abi (pcs_variant, false)) return false; - return aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count); + return aapcs_vfp_is_call_or_return_candidate (pcs_variant, mode, type, + &ag_mode, &count); } static bool aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, const_tree type) { - if (!(pcum->pcs_variant == ARM_PCS_AAPCS_VFP - || (pcum->pcs_variant == ARM_PCS_AAPCS_LOCAL - && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT))) + if (!use_vfp_abi (pcum->pcs_variant, false)) return false; - return aapcs_vfp_is_call_or_return_candidate (mode, type, + + return aapcs_vfp_is_call_or_return_candidate (pcum->pcs_variant, mode, type, &pcum->aapcs_vfp_rmode, &pcum->aapcs_vfp_rcount); } @@ -3934,10 +3955,9 @@ aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED) { - if (!(pcs_variant == ARM_PCS_AAPCS_VFP - || (pcs_variant == ARM_PCS_AAPCS_LOCAL - && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT))) + if (!use_vfp_abi (pcs_variant, false)) return false; + if (mode == BLKmode || (mode == TImode && !TARGET_NEON)) { int count; @@ -3946,7 +3966,8 @@ aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED, rtx par; int shift; - aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count); + aapcs_vfp_is_call_or_return_candidate (pcs_variant, mode, type, + &ag_mode, &count); if (!TARGET_NEON) { @@ -6316,7 +6337,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) case UMOD: if (TARGET_HARD_FLOAT && mode == SFmode) *total = COSTS_N_INSNS (2); - else if (TARGET_HARD_FLOAT && mode == DFmode) + else if (TARGET_HARD_FLOAT && mode == DFmode && !TARGET_VFP_SINGLE) *total = COSTS_N_INSNS (4); else *total = COSTS_N_INSNS (20); @@ -6394,7 +6415,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + if (TARGET_HARD_FLOAT + && (mode == SFmode + || (mode == DFmode && !TARGET_VFP_SINGLE))) { *total = COSTS_N_INSNS (1); if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE @@ -6489,7 +6512,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + if (TARGET_HARD_FLOAT + && (mode == SFmode + || (mode == DFmode && !TARGET_VFP_SINGLE))) { *total = COSTS_N_INSNS (1); if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE @@ -6602,7 +6627,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) case NEG: if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + if (TARGET_HARD_FLOAT + && (mode == SFmode + || (mode == DFmode && !TARGET_VFP_SINGLE))) { *total = COSTS_N_INSNS (1); return false; @@ -6751,7 +6778,9 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) case ABS: if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + if (TARGET_HARD_FLOAT + && (mode == SFmode + || (mode == DFmode && !TARGET_VFP_SINGLE))) { *total = COSTS_N_INSNS (1); return false; @@ -6854,7 +6883,8 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) return true; case CONST_DOUBLE: - if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x)) + if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x) + && (mode == SFmode || !TARGET_VFP_SINGLE)) *total = COSTS_N_INSNS (1); else *total = COSTS_N_INSNS (4); @@ -6929,7 +6959,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, return false; case MINUS: - if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) + if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT + && (mode == SFmode || !TARGET_VFP_SINGLE)) { *total = COSTS_N_INSNS (1); return false; @@ -6959,7 +6990,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, return false; case PLUS: - if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) + if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT + && (mode == SFmode || !TARGET_VFP_SINGLE)) { *total = COSTS_N_INSNS (1); return false; @@ -6999,7 +7031,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, return false; case NEG: - if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) + if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT + && (mode == SFmode || !TARGET_VFP_SINGLE)) { *total = COSTS_N_INSNS (1); return false; @@ -7023,7 +7056,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, return false; case ABS: - if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) + if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT + && (mode == SFmode || !TARGET_VFP_SINGLE)) *total = COSTS_N_INSNS (1); else *total = COSTS_N_INSNS (1 + ARM_NUM_REGS (mode)); @@ -7245,7 +7279,9 @@ arm_fastmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + if (TARGET_HARD_FLOAT + && (mode == SFmode + || (mode == DFmode && !TARGET_VFP_SINGLE))) { *total = COSTS_N_INSNS (1); return false; @@ -7402,7 +7438,9 @@ arm_9e_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) + if (TARGET_HARD_FLOAT + && (mode == SFmode + || (mode == DFmode && !TARGET_VFP_SINGLE))) { *total = COSTS_N_INSNS (1); return false; @@ -8341,6 +8379,8 @@ coproc_secondary_reload_class (enum machine_mode mode, rtx x, bool wb) { if (mode == HFmode) { + if (!TARGET_NEON_FP16) + return GENERAL_REGS; if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2)) return NO_REGS; return GENERAL_REGS; @@ -15055,6 +15095,30 @@ arm_print_operand (FILE *stream, rtx x, int code) } return; + /* Print the high single-precision register of a VFP double-precision + register. */ + case 'p': + { + int mode = GET_MODE (x); + int regno; + + if (GET_MODE_SIZE (mode) != 8 || GET_CODE (x) != REG) + { + output_operand_lossage ("invalid operand for code '%c'", code); + return; + } + + regno = REGNO (x); + if (!VFP_REGNO_OK_FOR_DOUBLE (regno)) + { + output_operand_lossage ("invalid operand for code '%c'", code); + return; + } + + fprintf (stream, "s%d", regno - FIRST_VFP_REGNUM + 1); + } + return; + /* Print a VFP/Neon double precision or quad precision register name. */ case 'P': case 'q': @@ -15973,10 +16037,9 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) return VFP_REGNO_OK_FOR_DOUBLE (regno); /* VFP registers can hold HFmode values, but there is no point in - putting them there unless we have the NEON extensions for - loading/storing them, too. */ + putting them there unless we have hardware conversion insns. */ if (mode == HFmode) - return TARGET_NEON_FP16 && VFP_REGNO_OK_FOR_SINGLE (regno); + return TARGET_FP16 && VFP_REGNO_OK_FOR_SINGLE (regno); if (TARGET_NEON) return (VALID_NEON_DREG_MODE (mode) && VFP_REGNO_OK_FOR_DOUBLE (regno)) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 2dfd22d..65d6708 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -230,10 +230,19 @@ extern void (*arm_lang_output_object_attributes_hook)(void); /* FPU supports VFPv3 instructions. */ #define TARGET_VFP3 (TARGET_VFP && arm_fpu_desc->rev >= 3) -/* FPU supports NEON/VFP half-precision floating-point. */ +/* FPU only supports VFP single-precision instructions. */ +#define TARGET_VFP_SINGLE (TARGET_VFP && arm_fpu_desc->regs == VFP_REG_SINGLE) + +/* FPU supports VFP double-precision instructions. */ +#define TARGET_VFP_DOUBLE (TARGET_VFP && arm_fpu_desc->regs != VFP_REG_SINGLE) + +/* FPU supports half-precision floating-point with NEON element load/store. */ #define TARGET_NEON_FP16 \ (TARGET_VFP && arm_fpu_desc->neon && arm_fpu_desc->fp16) +/* FPU supports VFP half-precision floating-point. */ +#define TARGET_FP16 (TARGET_VFP && 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 diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 52edcba..691bd55 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -958,7 +958,7 @@ [(set (match_operand:DF 0 "s_register_operand" "") (plus:DF (match_operand:DF 1 "s_register_operand" "") (match_operand:DF 2 "arm_float_add_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" " if (TARGET_MAVERICK && !cirrus_fp_register (operands[2], DFmode)) @@ -1196,7 +1196,7 @@ [(set (match_operand:DF 0 "s_register_operand" "") (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "") (match_operand:DF 2 "arm_float_rhs_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" " if (TARGET_MAVERICK) { @@ -1733,7 +1733,7 @@ [(set (match_operand:DF 0 "s_register_operand" "") (mult:DF (match_operand:DF 1 "s_register_operand" "") (match_operand:DF 2 "arm_float_rhs_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" " if (TARGET_MAVERICK && !cirrus_fp_register (operands[2], DFmode)) @@ -1753,7 +1753,7 @@ [(set (match_operand:DF 0 "s_register_operand" "") (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "") (match_operand:DF 2 "arm_float_rhs_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)" "") ;; Modulo insns @@ -3605,7 +3605,7 @@ (define_expand "negdf2" [(set (match_operand:DF 0 "s_register_operand" "") (neg:DF (match_operand:DF 1 "s_register_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)" "") ;; abssi2 doesn't really clobber the condition codes if a different register @@ -3691,7 +3691,7 @@ (define_expand "absdf2" [(set (match_operand:DF 0 "s_register_operand" "") (abs:DF (match_operand:DF 1 "s_register_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" "") (define_expand "sqrtsf2" @@ -3703,7 +3703,7 @@ (define_expand "sqrtdf2" [(set (match_operand:DF 0 "s_register_operand" "") (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)" "") (define_insn_and_split "one_cmpldi2" @@ -3814,7 +3814,7 @@ (define_expand "floatsidf2" [(set (match_operand:DF 0 "s_register_operand" "") (float:DF (match_operand:SI 1 "s_register_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" " if (TARGET_MAVERICK) { @@ -3866,7 +3866,7 @@ (define_expand "fix_truncdfsi2" [(set (match_operand:SI 0 "s_register_operand" "") (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" " if (TARGET_MAVERICK) { @@ -3883,7 +3883,7 @@ [(set (match_operand:SF 0 "s_register_operand" "") (float_truncate:SF (match_operand:DF 1 "s_register_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" "" ) @@ -4784,7 +4784,7 @@ (define_expand "extendsfdf2" [(set (match_operand:DF 0 "s_register_operand" "") (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" "" ) @@ -5971,7 +5971,7 @@ (define_insn "*arm32_movhf" [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r") (match_operand:HF 1 "general_operand" " m,r,r,F"))] - "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_NEON_FP16) + "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && ( s_register_operand (operands[0], HFmode) || s_register_operand (operands[1], HFmode))" "* @@ -6682,7 +6682,7 @@ (match_operand:DF 2 "arm_float_compare_operand" "")]) (label_ref (match_operand 3 "" "")) (pc)))] - "TARGET_32BIT && TARGET_HARD_FLOAT" + "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], operands[3])); DONE;" ) @@ -8296,7 +8296,7 @@ (if_then_else:DF (match_operand 1 "arm_comparison_operator" "") (match_operand:DF 2 "s_register_operand" "") (match_operand:DF 3 "arm_float_add_operand" "")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)" + "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)" " { enum rtx_code code = GET_CODE (operands[1]); diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index edb0215..c40d695 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -29,7 +29,7 @@ ;; in Thumb-1 state: I, J, K, L, M, N, O ;; The following multi-letter normal constraints have been used: -;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv +;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy ;; in Thumb-1 state: Pa, Pb ;; The following memory constraints have been used: @@ -207,10 +207,17 @@ (define_constraint "Dv" "@internal In ARM/Thumb-2 state a const_double which can be used with a VFP fconsts - or fconstd instruction." + instruction." (and (match_code "const_double") (match_test "TARGET_32BIT && vfp3_const_double_rtx (op)"))) +(define_constraint "Dy" + "@internal + In ARM/Thumb-2 state a const_double which can be used with a VFP fconstd + instruction." + (and (match_code "const_double") + (match_test "TARGET_32BIT && TARGET_VFP_DOUBLE && vfp3_const_double_rtx (op)"))) + (define_memory_constraint "Ut" "@internal In ARM/Thumb-2 state an address valid for loading/storing opaque structure diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 77c99d2..57c2192 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -145,7 +145,10 @@ case 4: return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; case 5: - return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; + if (TARGET_VFP_SINGLE) + return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\"; + else + return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; case 6: case 7: return output_move_vfp (operands); default: @@ -153,7 +156,14 @@ } " [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") - (set_attr "length" "8,8,8,4,4,4,4,4") + (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8) + (eq_attr "alternative" "5") + (if_then_else + (eq (symbol_ref "TARGET_VFP_SINGLE") + (const_int 1)) + (const_int 8) + (const_int 4))] + (const_int 4))) (set_attr "predicable" "yes") (set_attr "pool_range" "*,1020,*,*,*,*,1020,*") (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")] @@ -173,7 +183,10 @@ case 4: return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; case 5: - return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; + if (TARGET_VFP_SINGLE) + return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\"; + else + return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; case 6: case 7: return output_move_vfp (operands); default: @@ -181,13 +194,20 @@ } " [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_load,f_store") - (set_attr "length" "8,8,8,4,4,4,4,4") + (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8) + (eq_attr "alternative" "5") + (if_then_else + (eq (symbol_ref "TARGET_VFP_SINGLE") + (const_int 1)) + (const_int 8) + (const_int 4))] + (const_int 4))) (set_attr "pool_range" "*,4096,*,*,*,*,1020,*") (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")] ) ;; HFmode moves -(define_insn "*movhf_vfp" +(define_insn "*movhf_vfp_neon" [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r") (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))] "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16 @@ -241,6 +261,56 @@ (set_attr "length" "4,4,4,4,4,4,4,4,8")] ) +;; FP16 without element load/store instructions. +(define_insn "*movhf_vfp" + [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r") + (match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))] + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16 + && ( s_register_operand (operands[0], HFmode) + || s_register_operand (operands[1], HFmode))" + "* + switch (which_alternative) + { + case 0: /* ARM register from memory */ + return \"ldrh\\t%0, %1\\t%@ __fp16\"; + case 1: /* memory from ARM register */ + return \"strh\\t%1, %0\\t%@ __fp16\"; + case 2: /* S register from S register */ + return \"fcpys\\t%0, %1\"; + case 3: /* ARM register from ARM register */ + return \"mov\\t%0, %1\\t%@ __fp16\"; + case 4: /* S register from ARM register */ + return \"fmsr\\t%0, %1\"; + case 5: /* ARM register from S register */ + return \"fmrs\\t%0, %1\"; + case 6: /* ARM register from constant */ + { + REAL_VALUE_TYPE r; + long bits; + rtx ops[4]; + + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + bits = real_to_target (NULL, &r, HFmode); + ops[0] = operands[0]; + ops[1] = GEN_INT (bits); + ops[2] = GEN_INT (bits & 0xff00); + ops[3] = GEN_INT (bits & 0x00ff); + + if (arm_arch_thumb2) + output_asm_insn (\"movw\\t%0, %1\", ops); + else + output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); + return \"\"; + } + default: + gcc_unreachable (); + } + " + [(set_attr "conds" "unconditional") + (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*") + (set_attr "length" "4,4,4,4,4,4,8")] +) + ;; SFmode moves ;; Disparage the w<->r cases because reloading an invalid address is @@ -323,7 +393,7 @@ (define_insn "*movdf_vfp" [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r") - (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))] + (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,mF,r,UvF,w, w,r"))] "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && ( register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" @@ -336,13 +406,17 @@ case 1: return \"fmrrd%?\\t%Q0, %R0, %P1\"; case 2: + gcc_assert (TARGET_VFP_DOUBLE); return \"fconstd%?\\t%P0, #%G1\"; case 3: case 4: return output_move_double (operands); case 5: case 6: return output_move_vfp (operands); case 7: - return \"fcpyd%?\\t%P0, %P1\"; + if (TARGET_VFP_SINGLE) + return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\"; + else + return \"fcpyd%?\\t%P0, %P1\"; case 8: return \"#\"; default: @@ -352,7 +426,14 @@ " [(set_attr "type" "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") - (set_attr "length" "4,4,4,8,8,4,4,4,8") + (set (attr "length") (cond [(eq_attr "alternative" "3,4,8") (const_int 8) + (eq_attr "alternative" "7") + (if_then_else + (eq (symbol_ref "TARGET_VFP_SINGLE") + (const_int 1)) + (const_int 8) + (const_int 4))] + (const_int 4))) (set_attr "predicable" "yes") (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*") (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")] @@ -360,7 +441,7 @@ (define_insn "*thumb2_movdf_vfp" [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r") - (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))] + (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,mF,r,UvF,w, w,r"))] "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP" "* { @@ -371,13 +452,17 @@ case 1: return \"fmrrd%?\\t%Q0, %R0, %P1\"; case 2: + gcc_assert (TARGET_VFP_DOUBLE); return \"fconstd%?\\t%P0, #%G1\"; case 3: case 4: case 8: return output_move_double (operands); case 5: case 6: return output_move_vfp (operands); case 7: - return \"fcpyd%?\\t%P0, %P1\"; + if (TARGET_VFP_SINGLE) + return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\"; + else + return \"fcpyd%?\\t%P0, %P1\"; default: abort (); } @@ -385,7 +470,14 @@ " [(set_attr "type" "r_2_f,f_2_r,fconstd,load2,store2,f_load,f_store,ffarithd,*") - (set_attr "length" "4,4,4,8,8,4,4,4,8") + (set (attr "length") (cond [(eq_attr "alternative" "3,4,8") (const_int 8) + (eq_attr "alternative" "7") + (if_then_else + (eq (symbol_ref "TARGET_VFP_SINGLE") + (const_int 1)) + (const_int 8) + (const_int 4))] + (const_int 4))) (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*") (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")] ) @@ -446,7 +538,7 @@ [(match_operand 4 "cc_register" "") (const_int 0)]) (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] - "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "@ fcpyd%D3\\t%P0, %P2 fcpyd%d3\\t%P0, %P1 @@ -469,7 +561,7 @@ [(match_operand 4 "cc_register" "") (const_int 0)]) (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] - "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "@ it\\t%D3\;fcpyd%D3\\t%P0, %P2 it\\t%d3\;fcpyd%d3\\t%P0, %P1 @@ -500,7 +592,7 @@ (define_insn "*absdf2_vfp" [(set (match_operand:DF 0 "s_register_operand" "=w") (abs:DF (match_operand:DF 1 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fabsd%?\\t%P0, %P1" [(set_attr "predicable" "yes") (set_attr "type" "ffarithd")] @@ -520,12 +612,12 @@ (define_insn_and_split "*negdf2_vfp" [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r") (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "@ fnegd%?\\t%P0, %P1 # #" - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed && arm_general_register_operand (operands[0], DFmode)" [(set (match_dup 0) (match_dup 1))] " @@ -580,7 +672,7 @@ [(set (match_operand:DF 0 "s_register_operand" "=w") (plus:DF (match_operand:DF 1 "s_register_operand" "w") (match_operand:DF 2 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "faddd%?\\t%P0, %P1, %P2" [(set_attr "predicable" "yes") (set_attr "type" "faddd")] @@ -601,7 +693,7 @@ [(set (match_operand:DF 0 "s_register_operand" "=w") (minus:DF (match_operand:DF 1 "s_register_operand" "w") (match_operand:DF 2 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fsubd%?\\t%P0, %P1, %P2" [(set_attr "predicable" "yes") (set_attr "type" "faddd")] @@ -624,7 +716,7 @@ [(set (match_operand:DF 0 "s_register_operand" "+w") (div:DF (match_operand:DF 1 "s_register_operand" "w") (match_operand:DF 2 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fdivd%?\\t%P0, %P1, %P2" [(set_attr "predicable" "yes") (set_attr "type" "fdivd")] @@ -647,7 +739,7 @@ [(set (match_operand:DF 0 "s_register_operand" "+w") (mult:DF (match_operand:DF 1 "s_register_operand" "w") (match_operand:DF 2 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fmuld%?\\t%P0, %P1, %P2" [(set_attr "predicable" "yes") (set_attr "type" "fmuld")] @@ -668,7 +760,7 @@ [(set (match_operand:DF 0 "s_register_operand" "+w") (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w")) (match_operand:DF 2 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fnmuld%?\\t%P0, %P1, %P2" [(set_attr "predicable" "yes") (set_attr "type" "fmuld")] @@ -694,7 +786,7 @@ (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") (match_operand:DF 3 "s_register_operand" "w")) (match_operand:DF 1 "s_register_operand" "0")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fmacd%?\\t%P0, %P2, %P3" [(set_attr "predicable" "yes") (set_attr "type" "fmacd")] @@ -717,7 +809,7 @@ (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") (match_operand:DF 3 "s_register_operand" "w")) (match_operand:DF 1 "s_register_operand" "0")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fmscd%?\\t%P0, %P2, %P3" [(set_attr "predicable" "yes") (set_attr "type" "fmacd")] @@ -740,7 +832,7 @@ (minus:DF (match_operand:DF 1 "s_register_operand" "0") (mult:DF (match_operand:DF 2 "s_register_operand" "w") (match_operand:DF 3 "s_register_operand" "w"))))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fnmacd%?\\t%P0, %P2, %P3" [(set_attr "predicable" "yes") (set_attr "type" "fmacd")] @@ -766,7 +858,7 @@ (neg:DF (match_operand:DF 2 "s_register_operand" "w")) (match_operand:DF 3 "s_register_operand" "w")) (match_operand:DF 1 "s_register_operand" "0")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fnmscd%?\\t%P0, %P2, %P3" [(set_attr "predicable" "yes") (set_attr "type" "fmacd")] @@ -778,7 +870,7 @@ (define_insn "*extendsfdf2_vfp" [(set (match_operand:DF 0 "s_register_operand" "=w") (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fcvtds%?\\t%P0, %1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -787,7 +879,7 @@ (define_insn "*truncdfsf2_vfp" [(set (match_operand:SF 0 "s_register_operand" "=t") (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fcvtsd%?\\t%0, %P1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -796,7 +888,7 @@ (define_insn "extendhfsf2" [(set (match_operand:SF 0 "s_register_operand" "=t") (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" "vcvtb%?.f32.f16\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -805,7 +897,7 @@ (define_insn "truncsfhf2" [(set (match_operand:HF 0 "s_register_operand" "=t") (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" "vcvtb%?.f16.f32\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -823,7 +915,7 @@ (define_insn "*truncsidf2_vfp" [(set (match_operand:SI 0 "s_register_operand" "=t") (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "ftosizd%?\\t%0, %P1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -842,7 +934,7 @@ (define_insn "fixuns_truncdfsi2" [(set (match_operand:SI 0 "s_register_operand" "=t") (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "ftouizd%?\\t%0, %P1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -861,7 +953,7 @@ (define_insn "*floatsidf2_vfp" [(set (match_operand:DF 0 "s_register_operand" "=w") (float:DF (match_operand:SI 1 "s_register_operand" "t")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fsitod%?\\t%P0, %1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -880,7 +972,7 @@ (define_insn "floatunssidf2" [(set (match_operand:DF 0 "s_register_operand" "=w") (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fuitod%?\\t%P0, %1" [(set_attr "predicable" "yes") (set_attr "type" "f_cvt")] @@ -901,7 +993,7 @@ (define_insn "*sqrtdf2_vfp" [(set (match_operand:DF 0 "s_register_operand" "=w") (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "fsqrtd%?\\t%P0, %P1" [(set_attr "predicable" "yes") (set_attr "type" "fdivd")] @@ -953,9 +1045,9 @@ [(set (reg:CCFP CC_REGNUM) (compare:CCFP (match_operand:DF 0 "s_register_operand" "w") (match_operand:DF 1 "vfp_compare_operand" "wG")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "#" - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" [(set (reg:CCFP VFPCC_REGNUM) (compare:CCFP (match_dup 0) (match_dup 1))) @@ -968,9 +1060,9 @@ [(set (reg:CCFPE CC_REGNUM) (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w") (match_operand:DF 1 "vfp_compare_operand" "wG")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "#" - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" [(set (reg:CCFPE VFPCC_REGNUM) (compare:CCFPE (match_dup 0) (match_dup 1))) @@ -1010,7 +1102,7 @@ [(set (reg:CCFP VFPCC_REGNUM) (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w") (match_operand:DF 1 "vfp_compare_operand" "w,G")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "@ fcmpd%?\\t%P0, %P1 fcmpzd%?\\t%P0" @@ -1022,7 +1114,7 @@ [(set (reg:CCFPE VFPCC_REGNUM) (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w") (match_operand:DF 1 "vfp_compare_operand" "w,G")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "@ fcmped%?\\t%P0, %P1 fcmpezd%?\\t%P0" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e09c9ee..c9c759d 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -960,8 +960,9 @@ direct conversion. ARM provides hardware support for conversions between @code{__fp16} and @code{float} values as an extension to VFP and NEON (Advanced SIMD). GCC generates -code using the instructions provided by this extension if you compile -with the options @option{-mfpu=neon-fp16 -mfloat-abi=softfp}, +code using these hardware instructions if you compile with +options to select an FPU that provides them; +for example, @option{-mfpu=neon-fp16 -mfloat-abi=softfp}, in addition to the @option{-mfp16-format} option to select a half-precision format. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 20a9395..3b49707 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -9788,10 +9788,12 @@ of the @option{-mcpu=} option. Permissible names are: @samp{armv2}, @opindex mfp This specifies what floating point hardware (or hardware emulation) is available on the target. Permissible names are: @samp{fpa}, @samp{fpe2}, -@samp{fpe3}, @samp{maverick}, @samp{vfp}, @samp{vfpv3}, @samp{vfpv3-d16}, -@samp{neon}, and @samp{neon-fp16}. @option{-mfp} and @option{-mfpe} -are synonyms for @option{-mfpu}=@samp{fpe}@var{number}, for compatibility -with older versions of GCC@. +@samp{fpe3}, @samp{maverick}, @samp{vfp}, @samp{vfpv3}, @samp{vfpv3-fp16}, +@samp{vfpv3-d16}, @samp{vfpv3-d16-fp16}, @samp{vfpv3xd}, @samp{vfpv3xd-fp16}, +@samp{neon}, and @samp{neon-fp16}. +@option{-mfp} and @option{-mfpe} are synonyms for +@option{-mfpu}=@samp{fpe}@var{number}, for compatibility with older versions +of GCC@. If @option{-msoft-float} is specified this specifies the format of floating point values.