[ARM] Enable __fp16 as a function parameter and return type.
authorMatthew Wahab <matthew.wahab@arm.com>
Mon, 16 May 2016 09:31:58 +0000 (09:31 +0000)
committerMatthew Wahab <mwahab@gcc.gnu.org>
Mon, 16 May 2016 09:31:58 +0000 (09:31 +0000)
gcc/
2016-05-16  Matthew Wahab  <matthew.wahab@arm.com>
    Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
    Jiong Wang  <jiong.wang@arm.com>

* config/arm/arm-c.c (arm_cpu_builtins): Use def_or_undef_macro
for __ARM_FP16_FORMAT_IEEE and __ARM_FP16_FORMAT_ALTERNATIVE.
Define __ARM_FP16_ARGS when appropriate.
* config/arm/arm.c (arm_invalid_parameter_type): Remove
declaration.
(arm_invalid_return_type): Likewise.
(TARGET_INVALID_PARAMETER_TYPE): Remove.
(TARGET_INVALID_RETURN_TYPE): Remove.
(aapcs_vfp_sub_candidate): Allow HFmode.
(aapcs_vfp_allocate): Add comment.  Support HFmode.
(aapcs_vfp_allocate_return_reg): Likewise.
(struct aapcs_cp_arg_layout): Slightly reword comments for
is_return_candidate and allocate_return_reg.
(output_mov_vfp): Update assert.
(arm_hard_regno_mode_ok): Remove comment, update HF-mode
condition.
(arm_invalid_parameter_type): Remove.
(amr_invalid_return_type): Remove.
* config/arm/arm.h (TARGET_NEON_FP16): Fix definition.
* config/arm/arm.md (*arm32_movhf): Disable for TARGET_VFP.
* config/arm/vfp.md (*movhf_vfp): Enable for TARGET_VFP.

gcc/testsuite/
2016-05-16  Matthew Wahab  <matthew.wahab@arm.com>

* g++.dg/ext/arm-fp16/fp16-param-1.c: Update expected output.  Add
test for __ARM_FP16_ARGS.
* g++.dg/ext/arm-fp16/fp16-return-1.c: Update expected output.
* gcc.target/arm/aapcs/neon-vect10.c: New.
* gcc.target/arm/aapcs/neon-vect9.c: New.
* gcc.target/arm/aapcs/vfp18.c: New.
* gcc.target/arm/aapcs/vfp19.c: New.
* gcc.target/arm/aapcs/vfp20.c: New.
* gcc.target/arm/aapcs/vfp21.c: New.
* gcc.target/arm/fp16-aapcs-1.c: New.
* g++.target/arm/fp16-param-1.c: Update expected output.  Add
test for __ARM_FP16_ARGS.
* g++.target/arm/fp16-return-1.c: Update expected output.

Co-Authored-By: Jiong Wang <jiong.wang@arm.com>
Co-Authored-By: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
From-SVN: r236269

18 files changed:
gcc/ChangeLog
gcc/config/arm/arm-c.c
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/vfp.md
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C
gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C
gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/aapcs/vfp18.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/aapcs/vfp19.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/aapcs/vfp20.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/aapcs/vfp21.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/fp16-param-1.c
gcc/testsuite/gcc.target/arm/fp16-return-1.c

index 9f6b9b96657c2962304d835906e8602240dc36ac..4b7aeb535c818a7bb381998e0c87b64a61db0f77 100644 (file)
@@ -1,3 +1,29 @@
+2016-05-16  Matthew Wahab  <matthew.wahab@arm.com>
+           Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+           Jiong Wang  <jiong.wang@arm.com>
+
+       * config/arm/arm-c.c (arm_cpu_builtins): Use def_or_undef_macro
+       for __ARM_FP16_FORMAT_IEEE and __ARM_FP16_FORMAT_ALTERNATIVE.
+       Define __ARM_FP16_ARGS when appropriate.
+       * config/arm/arm.c (arm_invalid_parameter_type): Remove
+       declaration.
+       (arm_invalid_return_type): Likewise.
+       (TARGET_INVALID_PARAMETER_TYPE): Remove.
+       (TARGET_INVALID_RETURN_TYPE): Remove.
+       (aapcs_vfp_sub_candidate): Allow HFmode.
+       (aapcs_vfp_allocate): Add comment.  Support HFmode.
+       (aapcs_vfp_allocate_return_reg): Likewise.
+       (struct aapcs_cp_arg_layout): Slightly reword comments for
+       is_return_candidate and allocate_return_reg.
+       (output_mov_vfp): Update assert.
+       (arm_hard_regno_mode_ok): Remove comment, update HF-mode
+       condition.
+       (arm_invalid_parameter_type): Remove.
+       (amr_invalid_return_type): Remove.
+       * config/arm/arm.h (TARGET_NEON_FP16): Fix definition.
+       * config/arm/arm.md (*arm32_movhf): Disable for TARGET_VFP.
+       * config/arm/vfp.md (*movhf_vfp): Enable for TARGET_VFP.
+
 2016-05-16  Matthew Wahab  <matthew.wahab@arm.com>
 
        * config/aarch64/aarch64.h (LEGITIMIZE_RELOAD_ADDRESS): Remove.
index 4fbdfc50d03507380e4fb59883923a81d9367489..b98470fff45b20a5398c2534bc3bb3edfb7bfd01 100644 (file)
@@ -135,10 +135,12 @@ arm_cpu_builtins (struct cpp_reader* pfile)
   else
     cpp_undef (pfile, "__ARM_FP");
 
-  if (arm_fp16_format == ARM_FP16_FORMAT_IEEE)
-    builtin_define ("__ARM_FP16_FORMAT_IEEE");
-  if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
-    builtin_define ("__ARM_FP16_FORMAT_ALTERNATIVE");
+  def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
+                     arm_fp16_format == ARM_FP16_FORMAT_IEEE);
+  def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
+                     arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
+  def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
+                     arm_fp16_format != ARM_FP16_FORMAT_NONE);
 
   def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
   def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
index fbae1bcf5ea4d07735104a1841cf64a2664d6b0b..c3f74dcd58f9a1cfef2f9022d07aecc89868cb68 100644 (file)
@@ -249,8 +249,6 @@ static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
 static bool arm_output_addr_const_extra (FILE *, rtx);
 static bool arm_allocate_stack_slots_for_args (void);
 static bool arm_warn_func_return (tree);
-static const char *arm_invalid_parameter_type (const_tree t);
-static const char *arm_invalid_return_type (const_tree t);
 static tree arm_promoted_type (const_tree t);
 static tree arm_convert_to_type (tree type, tree expr);
 static bool arm_scalar_mode_supported_p (machine_mode);
@@ -657,12 +655,6 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS arm_preferred_reload_class
 
-#undef TARGET_INVALID_PARAMETER_TYPE
-#define TARGET_INVALID_PARAMETER_TYPE arm_invalid_parameter_type
-
-#undef TARGET_INVALID_RETURN_TYPE
-#define TARGET_INVALID_RETURN_TYPE arm_invalid_return_type
-
 #undef TARGET_PROMOTED_TYPE
 #define TARGET_PROMOTED_TYPE arm_promoted_type
 
@@ -5552,7 +5544,7 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
     {
     case REAL_TYPE:
       mode = TYPE_MODE (type);
-      if (mode != DFmode && mode != SFmode)
+      if (mode != DFmode && mode != SFmode && mode != HFmode)
        return -1;
 
       if (*modep == VOIDmode)
@@ -5800,11 +5792,16 @@ aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, machine_mode mode,
                                                &pcum->aapcs_vfp_rcount);
 }
 
+/* Implement the allocate field in aapcs_cp_arg_layout.  See the comment there
+   for the behaviour of this function.  */
+
 static bool
 aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, machine_mode mode,
                    const_tree type  ATTRIBUTE_UNUSED)
 {
-  int shift = GET_MODE_SIZE (pcum->aapcs_vfp_rmode) / GET_MODE_SIZE (SFmode);
+  int rmode_size
+    = MAX (GET_MODE_SIZE (pcum->aapcs_vfp_rmode), GET_MODE_SIZE (SFmode));
+  int shift = rmode_size / GET_MODE_SIZE (SFmode);
   unsigned mask = (1 << (shift * pcum->aapcs_vfp_rcount)) - 1;
   int regno;
 
@@ -5853,6 +5850,9 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, machine_mode mode,
   return false;
 }
 
+/* Implement the allocate_return_reg field in aapcs_cp_arg_layout.  See the
+   comment there for the behaviour of this function.  */
+
 static rtx
 aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED,
                               machine_mode mode,
@@ -5943,13 +5943,13 @@ static struct
      required for a return from FUNCTION_ARG.  */
   bool (*allocate) (CUMULATIVE_ARGS *, machine_mode, const_tree);
 
-  /* Return true if a result of mode MODE (or type TYPE if MODE is
-     BLKmode) is can be returned in this co-processor's registers.  */
+  /* Return true if a result of mode MODE (or type TYPE if MODE is BLKmode) can
+     be returned in this co-processor's registers.  */
   bool (*is_return_candidate) (enum arm_pcs, machine_mode, const_tree);
 
-  /* Allocate and return an RTX element to hold the return type of a
-     call, this routine must not fail and will only be called if
-     is_return_candidate returned true with the same parameters.  */
+  /* Allocate and return an RTX element to hold the return type of a call.  This
+     routine must not fail and will only be called if is_return_candidate
+     returned true with the same parameters.  */
   rtx (*allocate_return_reg) (enum arm_pcs, machine_mode, const_tree);
 
   /* Finish processing this argument and prepare to start processing
@@ -18610,7 +18610,8 @@ output_move_vfp (rtx *operands)
 
   gcc_assert (REG_P (reg));
   gcc_assert (IS_VFP_REGNUM (REGNO (reg)));
-  gcc_assert (mode == SFmode
+  gcc_assert ((mode == HFmode && TARGET_HARD_FLOAT && TARGET_VFP)
+             || mode == SFmode
              || mode == DFmode
              || mode == SImode
              || mode == DImode
@@ -23403,10 +23404,8 @@ arm_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
       if (mode == DFmode)
        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 hardware conversion insns. */
       if (mode == HFmode)
-       return TARGET_FP16 && VFP_REGNO_OK_FOR_SINGLE (regno);
+       return VFP_REGNO_OK_FOR_SINGLE (regno);
 
       if (TARGET_NEON)
         return (VALID_NEON_DREG_MODE (mode) && VFP_REGNO_OK_FOR_DOUBLE (regno))
@@ -23610,26 +23609,6 @@ arm_debugger_arg_offset (int value, rtx addr)
   return value;
 }
 \f
-/* Implement TARGET_INVALID_PARAMETER_TYPE.  */
-
-static const char *
-arm_invalid_parameter_type (const_tree t)
-{
-  if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
-    return N_("function parameters cannot have __fp16 type");
-  return NULL;
-}
-
-/* Implement TARGET_INVALID_PARAMETER_TYPE.  */
-
-static const char *
-arm_invalid_return_type (const_tree t)
-{
-  if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
-    return N_("functions cannot return __fp16 type");
-  return NULL;
-}
-
 /* Implement TARGET_PROMOTED_TYPE.  */
 
 static tree
index ad123dde991a3e4c4b9563ee6ebb84981767988f..5b1a03080d0a00fc1ef6934f6bce552e65230640 100644 (file)
@@ -194,7 +194,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
 /* FPU supports half-precision floating-point with NEON element load/store.  */
 #define TARGET_NEON_FP16                                               \
   (TARGET_VFP                                                          \
-   && ARM_FPU_FSET_HAS (TARGET_FPU_FEATURES, FPU_FL_NEON | FPU_FL_FP16))
+   && ARM_FPU_FSET_HAS (TARGET_FPU_FEATURES, FPU_FL_NEON)              \
+   && ARM_FPU_FSET_HAS (TARGET_FPU_FEATURES, FPU_FL_FP16))
 
 /* FPU supports VFP half-precision floating-point.  */
 #define TARGET_FP16                                                    \
index 7cf87efd70aa7b63ba73030cfa856595722d590f..4049f104c6d5fd8bfd8f68ecdfae6a3d34d4333f 100644 (file)
 (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_FP16)
+  "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
    && (          s_register_operand (operands[0], HFmode)
        || s_register_operand (operands[1], HFmode))"
   "*
index 6edea802b3b67597631bf7c7113ad3f63ed35e69..9750ba16260af5a10defc7cfcecd5e8f78039205 100644 (file)
 (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
+  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
+   && !TARGET_NEON_FP16
    && (   s_register_operand (operands[0], HFmode)
        || s_register_operand (operands[1], HFmode))"
   "*
index 88cc72684c873b05496cea7183fddfe3250e0be1..1598857f712c193acb4e6e77c9298545f5cf1181 100644 (file)
@@ -1,3 +1,19 @@
+2016-05-16  Matthew Wahab  <matthew.wahab@arm.com>
+
+       * g++.dg/ext/arm-fp16/fp16-param-1.c: Update expected output.  Add
+       test for __ARM_FP16_ARGS.
+       * g++.dg/ext/arm-fp16/fp16-return-1.c: Update expected output.
+       * gcc.target/arm/aapcs/neon-vect10.c: New.
+       * gcc.target/arm/aapcs/neon-vect9.c: New.
+       * gcc.target/arm/aapcs/vfp18.c: New.
+       * gcc.target/arm/aapcs/vfp19.c: New.
+       * gcc.target/arm/aapcs/vfp20.c: New.
+       * gcc.target/arm/aapcs/vfp21.c: New.
+       * gcc.target/arm/fp16-aapcs-1.c: New.
+       * g++.target/arm/fp16-param-1.c: Update expected output.  Add
+       test for __ARM_FP16_ARGS.
+       * g++.target/arm/fp16-return-1.c: Update expected output.
+
 2016-05-16  Jiong Wang  <jiong.wang@arm.com>
 
        PR testsuite/70227
index 03feb1a4d65d763e716aea5a951e3b12719b30df..e89da154c82c647b0c2f7577a06c77e2e9ae3785 100644 (file)
@@ -1,10 +1,14 @@
 /* { dg-do compile { target arm*-*-* } } */
 /* { dg-options "-mfp16-format=ieee" } */
 
-/* Functions cannot have parameters of type __fp16.  */
-extern void f (__fp16);                /* { dg-error "parameters cannot have __fp16 type" } */
-extern void (*pf) (__fp16);    /* { dg-error "parameters cannot have __fp16 type" } */
+/* Test that the ACLE macro is defined.  */
+#if __ARM_FP16_ARGS != 1
+#error Unexpected value for __ARM_FP16_ARGS
+#endif
+
+/* Test that __fp16 is supported as a parameter type.  */
+extern void f (__fp16);
+extern void (*pf) (__fp16);
 
-/* These should be OK.  */
 extern void g (__fp16 *);
 extern void (*pg) (__fp16 *);
index 406dfacd399db2ddce43dee18b8d3bc3952e58e7..b96532d18332410725ac151c2892e751efd304bf 100644 (file)
@@ -1,10 +1,9 @@
 /* { dg-do compile { target arm*-*-* } } */
 /* { dg-options "-mfp16-format=ieee" } */
 
-/* Functions cannot return type __fp16.  */
-extern __fp16 f (void);                /* { dg-error "cannot return __fp16" } */
-extern __fp16 (*pf) (void);    /* { dg-error "cannot return __fp16" } */
+/* Test that __fp16 is supported as a return type.  */
+extern __fp16 f (void);
+extern __fp16 (*pf) (void);
 
-/* These should be OK.  */
 extern __fp16 *g (void);
 extern __fp16 *(*pg) (void);
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c b/gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c
new file mode 100644 (file)
index 0000000..680a3b5
--- /dev/null
@@ -0,0 +1,31 @@
+/* Test AAPCS layout (VFP variant for Neon types) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-add-options arm_neon_fp16 } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define NEON
+#define TESTFILE "neon-vect10.c"
+#include "neon-constants.h"
+
+#include "abitest.h"
+#else
+
+ARG (int32x4_t, i32x4_constvec2, Q0) /* D0, D1.  */
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 3.0f, S4 + 2) /* D2, Q1.  */
+#else
+ARG (__fp16, 3.0f, S4) /* D2, Q1.  */
+#endif
+ARG (int32x4x2_t, i32x4x2_constvec1, Q2) /* Q2, Q3 - D4-D6 , s5-s12.  */
+ARG (double, 12.0, D3) /* Backfill this particular argument.  */
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 5.0f, S5 + 2) /* Backfill in S5.  */
+#else
+ARG (__fp16, 5.0f, S5) /* Backfill in S5.  */
+#endif
+ARG (int32x4x2_t, i32x4x2_constvec2, STACK)
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c b/gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c
new file mode 100644 (file)
index 0000000..fc2b13b
--- /dev/null
@@ -0,0 +1,23 @@
+/* Test AAPCS layout (VFP variant for Neon types) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-add-options arm_neon_fp16 } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define NEON
+#define TESTFILE "neon-vect9.c"
+#include "neon-constants.h"
+
+#include "abitest.h"
+#else
+
+ARG (int32x4_t, i32x4_constvec2, Q0) /* D0, D1.  */
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 3.0f, S4 + 2) /* D2, Q1 occupied.  */
+#else
+ARG (__fp16, 3.0f, S4) /* D2, Q1 occupied.  */
+#endif
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp18.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp18.c
new file mode 100644 (file)
index 0000000..225e9ce
--- /dev/null
@@ -0,0 +1,27 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } }  */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp18.c"
+#include "abitest.h"
+
+#else
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, S0 + 2)
+#else
+ARG (__fp16, 1.0f, S0)
+#endif
+ARG (float, 2.0f, S1)
+ARG (double, 4.0, D1)
+ARG (float, 2.0f, S4)
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, S5 + 2)
+#else
+ARG (__fp16, 1.0f, S5)
+#endif
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp19.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp19.c
new file mode 100644 (file)
index 0000000..8928b15
--- /dev/null
@@ -0,0 +1,29 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp19.c"
+
+__complex__ x = 1.0+2.0i;
+
+#include "abitest.h"
+#else
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, S0 + 2)
+#else
+ARG (__fp16, 1.0f, S0)
+#endif
+ARG (float, 2.0f, S1)
+ARG (__complex__ double, x, D1)
+ARG (float, 3.0f, S6)
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 2.0f, S7 + 2)
+#else
+ARG (__fp16, 2.0f, S7)
+#endif
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp20.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp20.c
new file mode 100644 (file)
index 0000000..61f0704
--- /dev/null
@@ -0,0 +1,21 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp20.c"
+
+#define PCSATTR __attribute__((pcs("aapcs")))
+
+#include "abitest.h"
+#else
+ARG (float, 1.0f, R0)
+ARG (double, 2.0, R2)
+ARG (float, 3.0f, STACK)
+ARG (__fp16, 2.0f, STACK+4)
+LAST_ARG (double, 4.0, STACK+8)
+#endif
+
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp21.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp21.c
new file mode 100644 (file)
index 0000000..15dff7d
--- /dev/null
@@ -0,0 +1,25 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp21.c"
+
+#define PCSATTR __attribute__((pcs("aapcs")))
+
+#include "abitest.h"
+#else
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, R0 + 2)
+#else
+ARG (__fp16, 1.0f, R0)
+#endif
+ARG (double, 2.0, R2)
+ARG (__fp16, 3.0f, STACK)
+ARG (float, 2.0f, STACK+4)
+LAST_ARG (double, 4.0, STACK+8)
+#endif
+
diff --git a/gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c b/gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c
new file mode 100644 (file)
index 0000000..5eab3e2
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile }  */
+/* { dg-require-effective-target arm_fp16_ok } */
+/* { dg-options "-mfp16-format=ieee -O2" }  */
+/* { dg-add-options arm_fp16 } */
+
+/* Test __fp16 arguments and return value in registers.  */
+
+__fp16 F (__fp16 a, __fp16 b, __fp16 c)
+{
+  if (a == b)
+    return c;
+  return a;
+}
+
+/* { dg-final { scan-assembler-times {vcvtb\.f32\.f16\ts[0-9]+, s0} 1 } }  */
+/* { dg-final { scan-assembler-times {vcvtb\.f32\.f16\ts[0-9]+, s1} 1 } }  */
+/* { dg-final { scan-assembler-times {vmov\ts0, r[0-9]+} 1 } }  */
index af4845f9fd5ba3cb06b2904d58eb8bcce50d3202..9c527301c449f30aacf25fe942ca419b0a313787 100644 (file)
@@ -1,10 +1,14 @@
 /* { dg-do compile } */
 /* { dg-options "-mfp16-format=ieee" } */
 
-/* Functions cannot have parameters of type __fp16.  */
-extern void f (__fp16);                /* { dg-error "parameters cannot have __fp16 type" } */
-extern void (*pf) (__fp16);    /* { dg-error "parameters cannot have __fp16 type" } */
+/* Test that the ACLE macro is defined.  */
+#if __ARM_FP16_ARGS != 1
+#error Unexpected value for __ARM_FP16_ARGS
+#endif
+
+/* Test that __fp16 is supported as a parameter type.  */
+extern void f (__fp16);
+extern void (*pf) (__fp16);
 
-/* These should be OK.  */
 extern void g (__fp16 *);
 extern void (*pg) (__fp16 *);
index f763941268ab0bdce84aa94a5ea8a229ef971ec6..f97a8d7f585ec1d184dbc85d475f08056fd5be35 100644 (file)
@@ -1,10 +1,9 @@
 /* { dg-do compile } */
 /* { dg-options "-mfp16-format=ieee" } */
 
-/* Functions cannot return type __fp16.  */
-extern __fp16 f (void);                /* { dg-error "cannot return __fp16" } */
-extern __fp16 (*pf) (void);    /* { dg-error "cannot return __fp16" } */
+/* Test that __fp16 is supported as a return type.  */
+extern __fp16 f (void);
+extern __fp16 (*pf) (void);
 
-/* These should be OK.  */
 extern __fp16 *g (void);
 extern __fp16 *(*pg) (void);