[Patch ARM 17/17] Enable _Float16 for ARM and fix PR target/63250
gcc/ PR target/63250 * config/arm/arm-builtins.c (arm_simd_floatHF_type_node): Rename to... (arm_fp16_type_node): ...This, make visibile. (arm_simd_builtin_std_type): Rename arm_simd_floatHF_type_node to arm_fp16_type_node. (arm_init_simd_builtin_types): Likewise. (arm_init_fp16_builtins): Likewise. * config/arm/arm.c (arm_excess_precision): New. (arm_floatn_mode): Likewise. (TARGET_C_EXCESS_PRECISION): Likewise. (TARGET_FLOATN_MODE): Likewise. (arm_promoted_type): Only promote arm_fp16_type_node. * config/arm/arm.h (arm_fp16_type_node): Declare. gcc/testsuite/ PR target/63250 * lib/target-supports.exp (add_options_for_float16): Add -mfp16-format=ieee when testign arm*-*-*. From-SVN: r242784
This commit is contained in:
parent
5e0f10a0f5
commit
5774b1fa53
@ -1,3 +1,19 @@
|
||||
2016-11-23 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
PR target/63250
|
||||
* config/arm/arm-builtins.c (arm_simd_floatHF_type_node): Rename to...
|
||||
(arm_fp16_type_node): ...This, make visibile.
|
||||
(arm_simd_builtin_std_type): Rename arm_simd_floatHF_type_node to
|
||||
arm_fp16_type_node.
|
||||
(arm_init_simd_builtin_types): Likewise.
|
||||
(arm_init_fp16_builtins): Likewise.
|
||||
* config/arm/arm.c (arm_excess_precision): New.
|
||||
(arm_floatn_mode): Likewise.
|
||||
(TARGET_C_EXCESS_PRECISION): Likewise.
|
||||
(TARGET_FLOATN_MODE): Likewise.
|
||||
(arm_promoted_type): Only promote arm_fp16_type_node.
|
||||
* config/arm/arm.h (arm_fp16_type_node): Declare.
|
||||
|
||||
2016-11-23 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
* config/arm/arm.c (arm_convert_to_type): Delete.
|
||||
|
@ -652,7 +652,8 @@ static struct arm_simd_type_info arm_simd_types [] = {
|
||||
};
|
||||
#undef ENTRY
|
||||
|
||||
static tree arm_simd_floatHF_type_node = NULL_TREE;
|
||||
/* The user-visible __fp16 type. */
|
||||
tree arm_fp16_type_node = NULL_TREE;
|
||||
static tree arm_simd_intOI_type_node = NULL_TREE;
|
||||
static tree arm_simd_intEI_type_node = NULL_TREE;
|
||||
static tree arm_simd_intCI_type_node = NULL_TREE;
|
||||
@ -739,7 +740,7 @@ arm_simd_builtin_std_type (enum machine_mode mode,
|
||||
case XImode:
|
||||
return arm_simd_intXI_type_node;
|
||||
case HFmode:
|
||||
return arm_simd_floatHF_type_node;
|
||||
return arm_fp16_type_node;
|
||||
case SFmode:
|
||||
return float_type_node;
|
||||
case DFmode:
|
||||
@ -840,8 +841,8 @@ arm_init_simd_builtin_types (void)
|
||||
/* Continue with standard types. */
|
||||
/* The __builtin_simd{64,128}_float16 types are kept private unless
|
||||
we have a scalar __fp16 type. */
|
||||
arm_simd_types[Float16x4_t].eltype = arm_simd_floatHF_type_node;
|
||||
arm_simd_types[Float16x8_t].eltype = arm_simd_floatHF_type_node;
|
||||
arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node;
|
||||
arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node;
|
||||
arm_simd_types[Float32x2_t].eltype = float_type_node;
|
||||
arm_simd_types[Float32x4_t].eltype = float_type_node;
|
||||
|
||||
@ -1754,11 +1755,11 @@ arm_init_iwmmxt_builtins (void)
|
||||
static void
|
||||
arm_init_fp16_builtins (void)
|
||||
{
|
||||
arm_simd_floatHF_type_node = make_node (REAL_TYPE);
|
||||
TYPE_PRECISION (arm_simd_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
|
||||
layout_type (arm_simd_floatHF_type_node);
|
||||
arm_fp16_type_node = make_node (REAL_TYPE);
|
||||
TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode);
|
||||
layout_type (arm_fp16_type_node);
|
||||
if (arm_fp16_format)
|
||||
(*lang_hooks.types.register_builtin_type) (arm_simd_floatHF_type_node,
|
||||
(*lang_hooks.types.register_builtin_type) (arm_fp16_type_node,
|
||||
"__fp16");
|
||||
}
|
||||
|
||||
|
@ -266,6 +266,7 @@ static bool arm_builtin_support_vector_misalignment (machine_mode mode,
|
||||
int misalignment,
|
||||
bool is_packed);
|
||||
static void arm_conditional_register_usage (void);
|
||||
static enum flt_eval_method arm_excess_precision (enum excess_precision_type);
|
||||
static reg_class_t arm_preferred_rename_class (reg_class_t rclass);
|
||||
static unsigned int arm_autovectorize_vector_sizes (void);
|
||||
static int arm_default_branch_cost (bool, bool);
|
||||
@ -299,6 +300,7 @@ static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
|
||||
static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
|
||||
int reloc);
|
||||
static void arm_expand_divmod_libfunc (rtx, machine_mode, rtx, rtx, rtx *, rtx *);
|
||||
static machine_mode arm_floatn_mode (int, bool);
|
||||
|
||||
/* Table of machine attributes. */
|
||||
static const struct attribute_spec arm_attribute_table[] =
|
||||
@ -444,6 +446,9 @@ static const struct attribute_spec arm_attribute_table[] =
|
||||
#undef TARGET_ASM_INTERNAL_LABEL
|
||||
#define TARGET_ASM_INTERNAL_LABEL arm_internal_label
|
||||
|
||||
#undef TARGET_FLOATN_MODE
|
||||
#define TARGET_FLOATN_MODE arm_floatn_mode
|
||||
|
||||
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
|
||||
#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
|
||||
|
||||
@ -734,6 +739,9 @@ static const struct attribute_spec arm_attribute_table[] =
|
||||
#undef TARGET_EXPAND_DIVMOD_LIBFUNC
|
||||
#define TARGET_EXPAND_DIVMOD_LIBFUNC arm_expand_divmod_libfunc
|
||||
|
||||
#undef TARGET_C_EXCESS_PRECISION
|
||||
#define TARGET_C_EXCESS_PRECISION arm_excess_precision
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Obstack for minipool constant handling. */
|
||||
@ -22512,7 +22520,9 @@ arm_debugger_arg_offset (int value, rtx addr)
|
||||
static tree
|
||||
arm_promoted_type (const_tree t)
|
||||
{
|
||||
if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
|
||||
if (SCALAR_FLOAT_TYPE_P (t)
|
||||
&& TYPE_PRECISION (t) == 16
|
||||
&& TYPE_MAIN_VARIANT (t) == arm_fp16_type_node)
|
||||
return float_type_node;
|
||||
return NULL_TREE;
|
||||
}
|
||||
@ -22534,6 +22544,61 @@ arm_scalar_mode_supported_p (machine_mode mode)
|
||||
return default_scalar_mode_supported_p (mode);
|
||||
}
|
||||
|
||||
/* Set the value of FLT_EVAL_METHOD.
|
||||
ISO/IEC TS 18661-3 defines two values that we'd like to make use of:
|
||||
|
||||
0: evaluate all operations and constants, whose semantic type has at
|
||||
most the range and precision of type float, to the range and
|
||||
precision of float; evaluate all other operations and constants to
|
||||
the range and precision of the semantic type;
|
||||
|
||||
N, where _FloatN is a supported interchange floating type
|
||||
evaluate all operations and constants, whose semantic type has at
|
||||
most the range and precision of _FloatN type, to the range and
|
||||
precision of the _FloatN type; evaluate all other operations and
|
||||
constants to the range and precision of the semantic type;
|
||||
|
||||
If we have the ARMv8.2-A extensions then we support _Float16 in native
|
||||
precision, so we should set this to 16. Otherwise, we support the type,
|
||||
but want to evaluate expressions in float precision, so set this to
|
||||
0. */
|
||||
|
||||
static enum flt_eval_method
|
||||
arm_excess_precision (enum excess_precision_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EXCESS_PRECISION_TYPE_FAST:
|
||||
case EXCESS_PRECISION_TYPE_STANDARD:
|
||||
/* We can calculate either in 16-bit range and precision or
|
||||
32-bit range and precision. Make that decision based on whether
|
||||
we have native support for the ARMv8.2-A 16-bit floating-point
|
||||
instructions or not. */
|
||||
return (TARGET_VFP_FP16INST
|
||||
? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
|
||||
: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
|
||||
case EXCESS_PRECISION_TYPE_IMPLICIT:
|
||||
return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
return FLT_EVAL_METHOD_UNPREDICTABLE;
|
||||
}
|
||||
|
||||
|
||||
/* Implement TARGET_FLOATN_MODE. Make very sure that we don't provide
|
||||
_Float16 if we are using anything other than ieee format for 16-bit
|
||||
floating point. Otherwise, punt to the default implementation. */
|
||||
static machine_mode
|
||||
arm_floatn_mode (int n, bool extended)
|
||||
{
|
||||
if (!extended && n == 16)
|
||||
return arm_fp16_format == ARM_FP16_FORMAT_IEEE ? HFmode : VOIDmode;
|
||||
|
||||
return default_floatn_mode (n, extended);
|
||||
}
|
||||
|
||||
|
||||
/* Set up OPERANDS for a register copy from SRC to DEST, taking care
|
||||
not to early-clobber SRC registers in the process.
|
||||
|
||||
|
@ -73,6 +73,11 @@ extern int arm_ccfsm_state;
|
||||
extern GTY(()) rtx arm_target_insn;
|
||||
/* Callback to output language specific object attributes. */
|
||||
extern void (*arm_lang_output_object_attributes_hook)(void);
|
||||
|
||||
/* This type is the user-visible __fp16. We need it in a few places in
|
||||
the backend. Defined in arm-builtins.c. */
|
||||
extern tree arm_fp16_type_node;
|
||||
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(subtarget_cpp_spec) \
|
||||
|
@ -1,3 +1,9 @@
|
||||
2016-11-23 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
PR target/63250
|
||||
* lib/target-supports.exp (add_options_for_float16): Add
|
||||
-mfp16-format=ieee when testign arm*-*-*.
|
||||
|
||||
2016-11-23 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
* gcc.target/arm/fp16-rounding-alt-1.c (ROUNDED): Change expected
|
||||
|
@ -2626,6 +2626,9 @@ proc check_effective_target_floatn_nx_runtime {} {
|
||||
# the function name.
|
||||
|
||||
proc add_options_for_float16 { flags } {
|
||||
if { [istarget arm*-*-*] } {
|
||||
return "$flags -mfp16-format=ieee"
|
||||
}
|
||||
return "$flags"
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user