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_fp16_type_node,
- "__fp16");
+ (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node, "__fp16");
}
void
#include "arm-mve-builtins.def"
for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
{
- if (vector_types[i].requires_float && !TARGET_HAVE_MVE_FLOAT)
- continue;
tree eltype = scalar_types[i];
tree vectype;
if (eltype == boolean_type_node)
static void
register_vector_type (vector_type_index type)
{
-
- /* If the target does not have the mve.fp extension, but the type requires
- it, then it needs to be assigned a non-dummy type so that functions
- with those types in their signature can be registered. This allows for
- diagnostics about the missing extension, rather than about a missing
- function definition. */
- if (vector_types[type].requires_float && !TARGET_HAVE_MVE_FLOAT)
- {
- acle_vector_types[0][type] = void_type_node;
- return;
- }
-
tree vectype = abi_vector_types[type];
tree id = get_identifier (vector_types[type].acle_name);
tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
{
const vector_type_info* info = &vector_types[type];
- /* If the target does not have the mve.fp extension, but the type requires
- it, then it needs to be assigned a non-dummy type so that functions
- with those types in their signature can be registered. This allows for
- diagnostics about the missing extension, rather than about a missing
- function definition. */
- if (scalar_types[type] == boolean_type_node
- || (info->requires_float && !TARGET_HAVE_MVE_FLOAT))
+ if (scalar_types[type] == boolean_type_node)
{
for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
acle_vector_types[num_vectors >> 1][type] = void_type_node;
*/
enum arm_fp16_format_type
{
+ ARM_FP16_FORMAT_DEFAULT = -1,
ARM_FP16_FORMAT_NONE = 0,
ARM_FP16_FORMAT_IEEE = 1,
ARM_FP16_FORMAT_ALTERNATIVE = 2
arm_arch_bf16 = bitmap_bit_p (arm_active_target.isa, isa_bit_bf16);
arm_fp16_inst = bitmap_bit_p (arm_active_target.isa, isa_bit_fp16);
- if (arm_fp16_inst)
+
+ /* Set arm_fp16_format to IEEE if the target has fp16 support unless user
+ forced ARM_FP16_FORMAT_NONE. */
+ if (arm_fp16_inst && (arm_fp16_format != ARM_FP16_FORMAT_NONE))
{
if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
error ("selected fp16 options are incompatible");
arm_fp16_format = ARM_FP16_FORMAT_IEEE;
}
+ if (arm_fp16_format == ARM_FP16_FORMAT_DEFAULT)
+ arm_fp16_format = ARM_FP16_FORMAT_NONE;
+
arm_arch_cde = 0;
arm_arch_cde_coproc = 0;
int cde_bits[] = {isa_bit_cdecp0, isa_bit_cdecp1, isa_bit_cdecp2,
return true;
if (TARGET_HAVE_MVE
- && (VALID_MVE_SI_MODE (mode) || VALID_MVE_PRED_MODE (mode)))
- return true;
-
- if (TARGET_HAVE_MVE_FLOAT
- && (mode == V2DFmode || mode == V4SFmode || mode == V8HFmode))
+ && (VALID_MVE_MODE (mode) || VALID_MVE_PRED_MODE (mode)))
return true;
return false;
Switch ARM/Thumb modes on alternating functions for compiler testing.
mfp16-format=
-Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) Init(ARM_FP16_FORMAT_NONE)
+Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) Init(ARM_FP16_FORMAT_DEFAULT)
Specify the __fp16 floating-point format.
Enum
#ifndef _GCC_ARM_MVE_TYPES_H
#define _GCC_ARM_MVE_TYPES_H
-#if (__ARM_FEATURE_MVE & 2) /* MVE Floating point. */
typedef __fp16 float16_t;
typedef float float32_t;
-#endif
#pragma GCC arm "arm_mve_types.h"
(FP) along with M-Profile Vector Extension (MVE). Some multilibs may be
incompatible with these options.
+@item arm_v8_1m_mve_nofp_ok
+ARM target supports options to generate instructions from ARMv8.1-M
+with the M-Profile Vector Extension (MVE) but without the
+Half-precision floating-point instructions (HP) and Floating-point
+Extension (FP). Some multilibs may be incompatible with these options.
+
@item arm_mve_hw
Test system supports executing MVE instructions.
void
f1 (uint8x16_t v)
{
- vreinterpretq_f16 (v); /* { dg-error {ACLE function 'void vreinterpretq_f16\(uint8x16_t\)' requires ISA extension 'mve.fp'} } */
+ vreinterpretq_f16 (v); /* { dg-error {ACLE function 'float16x8_t vreinterpretq_f16\(uint8x16_t\)' requires ISA extension 'mve.fp'} } */
/* { dg-message {note: you can enable mve.fp by using the command-line option '-march', or by using the 'target' attribute or pragma} "" {target *-*-*} .-1 } */
}
+++ /dev/null
-/* { dg-do compile } */
-/* { dg-require-effective-target arm_fp16_none_ok } */
-/* { dg-options "-mfp16-format=none" } */
-
-/* __fp16 type name is not recognized unless you explicitly enable it
- by selecting -mfp16-format=ieee or -mfp16-format=alternative. */
-__fp16 xx = 0.0; /* { dg-error "unknown type name" } */
--- /dev/null
+/* Check that we can compile if the target does not support floating-point, but
+ we use a pragma to enable FP support locally. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma GCC target ("arch=armv8.1-m.main+mve.fp")
+
+/*
+**foo:
+** ...
+** vldrh.16 q[0-9]+, \[(?:ip|fp|r[0-9]+)\](?: @.*|)
+** ...
+*/
+float16x8_t
+foo (float16_t const *base)
+{
+ return vld1q_f16 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* Check that we can compile if the target does not support floating-point, but
+ we use a pragma to enable FP support locally. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma GCC target ("arch=armv8.1-m.main+mve.fp")
+
+/*
+**foo:
+** ...
+** vldrw.32 q[0-9]+, \[(?:ip|fp|r[0-9]+)\](?: @.*|)
+** ...
+*/
+float32x4_t
+foo (float32_t const *base)
+{
+ return vld1q_f32 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* Check that we can compile if the target supports floating-point. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float16x8_t
+foo (float16_t const *base)
+{
+ return vld1q_f16 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* Check that we can compile if the target supports floating-point. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float32x4_t
+foo (float32_t const *base)
+{
+ return vld1q_f32 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* Check that -mfp16-format=none works. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_mve_fp } */
+/* { dg-additional-options "-O2 -mfp16-format=none" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float16x8_t
+foo (float16_t const *base)
+{
+ return vld1q_f16 (base);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not {eabi_attribute 38,} } } */
--- /dev/null
+/* Check that we get an error if the target does not support floating-point: we
+ force +mve to cancel a possible implicit +mve.fp. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float16x8_t
+foo (float16_t const *base)
+{
+ return vld1q_f16 (base); /* { dg-error {ACLE function '.*vld1q_f16.*' requires ISA extension 'mve.fp'} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* Check that we get an error if the target does not support floating-point: we
+ force +mve to cancel a possible implicit +mve.fp. */
+
+/* { dg-require-effective-target arm_v8_1m_mve_nofp_ok } */
+/* { dg-add-options arm_v8_1m_mve_nofp } */
+/* { dg-additional-options "-O2" } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float32x4_t
+foo (float32_t const *base)
+{
+ return vld1q_f32 (base); /* { dg-error {ACLE function '.*vld1q_f32.*' requires ISA extension 'mve.fp'} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
return "$flags $et_arm_v8_1m_mve_flags"
}
+# Return 1 if the target supports ARMv8.1-M MVE without floating point
+# instructions, 0 otherwise. The test is valid for ARM.
+# Record the command line options needed.
+
+proc check_effective_target_arm_v8_1m_mve_nofp_ok_nocache { } {
+ global et_arm_v8_1m_mve_nofp_flags
+ set et_arm_v8_1m_mve_nofp_flags ""
+
+ if { ![istarget arm*-*-*] } {
+ return 0;
+ }
+
+ # Iterate through sets of options to find the compiler flags that
+ # need to be added to the -march option.
+ foreach flags {
+ ""
+ "-mfloat-abi=softfp"
+ "-mfpu=auto -mcpu=unset -march=armv8.1-m.main+mve"
+ "-mfpu=auto -mcpu=unset -march=armv8.1-m.main+mve -mfloat-abi=softfp"
+ } {
+ if { [check_no_compiler_messages_nocache \
+ arm_v8_1m_mve_ok object {
+ #if !defined (__ARM_FEATURE_MVE)
+ #error "__ARM_FEATURE_MVE not defined"
+ #endif
+ #if (__ARM_FEATURE_MVE & 2)
+ #error "__ARM_FEATURE_MVE for floating point defined"
+ #endif
+ #if __ARM_BIG_ENDIAN
+ #error "MVE intrinsics are not supported in Big-Endian mode."
+ #endif
+ #include <arm_mve.h>
+ } "$flags -mthumb"] } {
+ set et_arm_v8_1m_mve_nofp_flags "$flags -mthumb --save-temps"
+ return 1
+ }
+ }
+
+ return 0;
+}
+
+proc check_effective_target_arm_v8_1m_mve_nofp_ok { } {
+ return [check_cached_effective_target arm_v8_1m_mve_nofp_ok \
+ check_effective_target_arm_v8_1m_mve_nofp_ok_nocache]
+}
+
+proc add_options_for_arm_v8_1m_mve_nofp { flags } {
+ if { ! [check_effective_target_arm_v8_1m_mve_nofp_ok] } {
+ return "$flags"
+ }
+ global et_arm_v8_1m_mve_nofp_flags
+ return "$flags $et_arm_v8_1m_mve_nofp_flags"
+}
+
proc check_effective_target_arm_v8_2a_dotprod_neon_ok { } {
return [check_cached_effective_target arm_v8_2a_dotprod_neon_ok \
check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache]