]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/61483 ([AArch64] builtin va_start incorrectly initializes the field...
authorYufeng Zhang <yufeng.zhang@arm.com>
Tue, 17 Jun 2014 09:39:22 +0000 (09:39 +0000)
committerYufeng Zhang <yufeng@gcc.gnu.org>
Tue, 17 Jun 2014 09:39:22 +0000 (09:39 +0000)
gcc/

PR target/61483
* config/aarch64/aarch64.c (aarch64_layout_arg): Add new local
variable 'size'; calculate 'size' right in the front; use
'size' to compute 'nregs' (when 'allocate_ncrn != 0') and
pcum->aapcs_stack_words.

gcc/testsuite/

PR target/61483
* gcc.target/aarch64/aapcs64/type-def.h (struct hfa_fx2_t): New type.
* gcc.target/aarch64/aapcs64/va_arg-13.c: New test.
* gcc.target/aarch64/aapcs64/va_arg-14.c: Ditto.
* gcc.target/aarch64/aapcs64/va_arg-15.c: Ditto.

From-SVN: r211733

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h
gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-13.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-14.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-15.c [new file with mode: 0644]

index c5bd236e64fc518954f7e73637130820acba0642..08353945c20b41125d098cf1463fec6e7ec3dfb9 100644 (file)
@@ -1,3 +1,11 @@
+2014-06-17  Yufeng Zhang  <yufeng.zhang@arm.com>
+
+       PR target/61483
+       * config/aarch64/aarch64.c (aarch64_layout_arg): Add new local
+       variable 'size'; calculate 'size' right in the front; use
+       'size' to compute 'nregs' (when 'allocate_ncrn != 0') and
+       pcum->aapcs_stack_words.
+
 2014-06-17  Nick Clifton  <nickc@redhat.com>
 
        * config/msp430/msp430.md (mulhisi3): Add a NOP after the DINT.
index 10fb7de3ba424576700b92291d41672f2d9b59dd..e0c25e7afef0a5d66d7a0111df44423cfe387b00 100644 (file)
@@ -1504,6 +1504,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode,
   CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
   int ncrn, nvrn, nregs;
   bool allocate_ncrn, allocate_nvrn;
+  HOST_WIDE_INT size;
 
   /* We need to do this once per argument.  */
   if (pcum->aapcs_arg_processed)
@@ -1511,6 +1512,11 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode,
 
   pcum->aapcs_arg_processed = true;
 
+  /* Size in bytes, rounded to the nearest multiple of 8 bytes.  */
+  size
+    = AARCH64_ROUND_UP (type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode),
+                       UNITS_PER_WORD);
+
   allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode);
   allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v,
                                                 mode,
@@ -1561,9 +1567,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode,
     }
 
   ncrn = pcum->aapcs_ncrn;
-  nregs = ((type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode))
-          + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-
+  nregs = size / UNITS_PER_WORD;
 
   /* C6 - C9.  though the sign and zero extension semantics are
      handled elsewhere.  This is the case where the argument fits
@@ -1612,13 +1616,12 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode,
   pcum->aapcs_nextncrn = NUM_ARG_REGS;
 
   /* The argument is passed on stack; record the needed number of words for
-     this argument (we can re-use NREGS) and align the total size if
-     necessary.  */
+     this argument and align the total size if necessary.  */
 on_stack:
-  pcum->aapcs_stack_words = nregs;
+  pcum->aapcs_stack_words = size / UNITS_PER_WORD;
   if (aarch64_function_arg_alignment (mode, type) == 16 * BITS_PER_UNIT)
     pcum->aapcs_stack_size = AARCH64_ROUND_UP (pcum->aapcs_stack_size,
-                                              16 / UNITS_PER_WORD) + 1;
+                                              16 / UNITS_PER_WORD);
   return;
 }
 
index 97270b29bb529e5d8b4bbe5231bddef32984a56b..d2ed776e1cbcb6d667552fbe3a85e7f1e28d874f 100644 (file)
@@ -1,3 +1,11 @@
+2014-06-17  Yufeng Zhang  <yufeng.zhang@arm.com>
+
+       PR target/61483
+       * gcc.target/aarch64/aapcs64/type-def.h (struct hfa_fx2_t): New type.
+       * gcc.target/aarch64/aapcs64/va_arg-13.c: New test.
+       * gcc.target/aarch64/aapcs64/va_arg-14.c: Ditto.
+       * gcc.target/aarch64/aapcs64/va_arg-15.c: Ditto.
+
 2014-06-17  Richard Biener  <rguenther@suse.de>
 
        PR lto/61012
index a95d06aa2edac5428b81575e90909c37460b0e45..07e56fff857476d6d105725e7057257584c74e74 100644 (file)
@@ -34,6 +34,13 @@ struct hfa_fx2_t
   float b;
 };
 
+struct hfa_fx3_t
+{
+  float a;
+  float b;
+  float c;
+};
+
 struct hfa_dx2_t
 {
   double a;
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-13.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-13.c
new file mode 100644 (file)
index 0000000..ae1e3ec
--- /dev/null
@@ -0,0 +1,59 @@
+/* Test AAPCS64 layout and __builtin_va_start.
+
+   Pass named HFA/HVA argument on stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg-13.c"
+
+struct float_float_t
+{
+  float a;
+  float b;
+} float_float;
+
+union float_int_t
+{
+  float b8;
+  int b5;
+} float_int;
+
+#define HAS_DATA_INIT_FUNC
+void
+init_data ()
+{
+  float_float.a = 1.2f;
+  float_float.b = 2.2f;
+
+  float_int.b8 = 4983.80f;
+}
+
+#include "abitest.h"
+#else
+  ARG (float, 1.0f, S0, 0)
+  ARG (float, 2.0f, S1, 1)
+  ARG (float, 3.0f, S2, 2)
+  ARG (float, 4.0f, S3, 3)
+  ARG (float, 5.0f, S4, 4)
+  ARG (float, 6.0f, S5, 5)
+  ARG (float, 7.0f, S6, 6)
+  ARG (struct float_float_t, float_float, STACK, 7)
+  ARG (int,  9, W0, 8)
+  ARG (int, 10, W1, 9)
+  ARG (int, 11, W2, 10)
+  ARG (int, 12, W3, 11)
+  ARG (int, 13, W4, 12)
+  ARG (int, 14, W5, 13)
+  ARG (int, 15, W6, LAST_NAMED_ARG_ID)
+  DOTS
+  /* Note on the reason of using 'X7' instead of 'W7' here:
+     Using 'X7' makes sure the test works in the big-endian mode.
+     According to PCS rules B.4 and C.10, the size of float_int is rounded
+     to 8 bytes and prepared in the register X7 as if loaded via LDR from
+     the memory, with the content of the other 4 bytes unspecified.  The
+     test framework will only compare the 4 relavent bytes.  */
+  ANON (union float_int_t, float_int, X7, 15)
+  LAST_ANON (long long, 12683143434LL, STACK + 8, 16)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-14.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-14.c
new file mode 100644 (file)
index 0000000..91080d5
--- /dev/null
@@ -0,0 +1,35 @@
+/* Test AAPCS64 layout and __builtin_va_start.
+
+   Pass named HFA/HVA argument on stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg-14.c"
+#include "type-def.h"
+
+struct hfa_fx2_t hfa_fx2 = {1.2f, 2.2f};
+struct hfa_fx3_t hfa_fx3 = {3.2f, 4.2f, 5.2f};
+vf4_t float32x4 = {6.2f, 7.2f, 8.2f, 9.2f};
+vf4_t float32x4_2 = {10.2f, 11.2f, 12.2f, 13.2f};
+
+#include "abitest.h"
+#else
+  ARG (float, 1.0f, S0, 0)
+  ARG (float, 2.0f, S1, 1)
+  ARG (float, 3.0f, S2, 2)
+  ARG (float, 4.0f, S3, 3)
+  ARG (float, 5.0f, S4, 4)
+  ARG (float, 6.0f, S5, 5)
+  ARG (float, 7.0f, S6, 6)
+  ARG (struct hfa_fx3_t, hfa_fx3, STACK, 7)
+  /* Previous argument size has been rounded up to the nearest multiple of
+     8 bytes.  */
+  ARG (struct hfa_fx2_t, hfa_fx2, STACK + 16, 8)
+  /* NSAA is rounded up to the nearest natural alignment of float32x4.  */
+  ARG (vf4_t, float32x4, STACK + 32, 9)
+  ARG (vf4_t, float32x4_2, STACK + 48, LAST_NAMED_ARG_ID)
+  DOTS
+  LAST_ANON (double, 123456789.987, STACK + 64, 11)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-15.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-15.c
new file mode 100644 (file)
index 0000000..d8fdb32
--- /dev/null
@@ -0,0 +1,39 @@
+/* Test AAPCS64 layout and __builtin_va_start.
+
+   Pass named __128int argument on stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg-15.c"
+#include "type-def.h"
+
+union int128_t qword;
+
+#define HAS_DATA_INIT_FUNC
+void
+init_data ()
+{
+  /* Init signed quad-word integer.  */
+  qword.l64 = 0xfdb9753102468aceLL;
+  qword.h64 = 0xeca8642013579bdfLL;
+}
+
+#include "abitest.h"
+#else
+  ARG (int, 1, W0, 0)
+  ARG (int, 2, W1, 1)
+  ARG (int, 3, W2, 2)
+  ARG (int, 4, W3, 3)
+  ARG (int, 5, W4, 4)
+  ARG (int, 6, W5, 5)
+  ARG (int, 7, W6, 6)
+  ARG (__int128, qword.i, STACK, LAST_NAMED_ARG_ID)
+  DOTS
+#ifndef __AAPCS64_BIG_ENDIAN__
+  LAST_ANON (int, 8, STACK + 16, 8)
+#else
+  LAST_ANON (int, 8, STACK + 20, 8)
+#endif
+#endif