diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp
index 3e652c483c7..caa6e5b9b81 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp
@@ -88,4 +88,12 @@ foreach src [lsort [glob -nocomplain $srcdir/$subdir/ice_*.c]] {
     }
 }
 
+# Test DFP support
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/dfp*.c]] {
+    if {[runtest_file_p $runtests $src]} {
+	    c-torture [list $src] \
+			    $additional_flags
+    }
+}
+
 torture-finish
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/dfp-1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/dfp-1.c
new file mode 100644
index 00000000000..95868102495
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/dfp-1.c
@@ -0,0 +1,24 @@
+/* Test loading DFP values from memory.  */
+
+/* { dg-do compile { target aarch64*-*-* } } */
+
+_Decimal32 var32 = 1.2df;
+
+int foo32(_Decimal32 param32)
+{
+	return param32 == var32;
+}
+
+_Decimal64 var64 = 1.2df;
+
+int foo64(_Decimal64 param64)
+{
+	return param64 == var64;
+}
+
+_Decimal128 var128 = 1.2df;
+
+int foo128(_Decimal128 param128)
+{
+	return param128 == var128;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
index 29a1ca6d45b..5405e1e4920 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
@@ -14,6 +14,8 @@ vf2_t vf2 = (vf2_t){ 17.f, 18.f };
 vi4_t vi4 = (vi4_t){ 0xdeadbabe, 0xbabecafe, 0xcafebeef, 0xbeefdead };
 vlf1_t vlf1 = (vlf1_t) { 17.0 };
 
+vldf1_t vldf1 = (vldf1_t) { 17.0dl };
+
 union int128_t qword;
 
 int *int_ptr = (int *)0xabcdef0123456789ULL;
@@ -45,4 +47,9 @@ FUNC_VAL_CHECK (13,         vi4_t,        vi4, Q0, i32in128)
 FUNC_VAL_CHECK (14,         int *,    int_ptr, X0, flat)
 FUNC_VAL_CHECK (15,         vlf1_t,    vlf1, Q0, flat)
 FUNC_VAL_CHECK (16,         __fp16,    0xabcd, H0, flat)
+
+FUNC_VAL_CHECK (17,     _Decimal32, 65432.12345df, S0, flat)
+FUNC_VAL_CHECK (18,     _Decimal64, 9876543.212345dd, D0, flat)
+FUNC_VAL_CHECK (19,    _Decimal128, 98765432123456789.987654321dl, Q0, flat)
+FUNC_VAL_CHECK (20,        vldf1_t, vldf1, Q0, flat)
 #endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
index ff9b7e6d4b8..ad312b675b9 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
@@ -30,6 +30,23 @@ struct non_hfa_fffd_t non_hfa_fffd = {33.f, 34.f, 35.f, 36.0};
 union hfa_union_t hfa_union;
 union non_hfa_union_t non_hfa_union;
 
+/* Decimal Floating-point.  */
+struct hfa_dfx1_t hfa_dfx1 = {12.345df};
+struct hfa_dfx2_t hfa_dfx2 = {123.456df, 234.456df};
+struct hfa_ddx2_t hfa_ddx2 = {234.567dd, 345.678dd};
+struct hfa_ddx4_t hfa_ddx4 = {1234.123dd, 2345.234dd, 3456.345dd, 4567.456dd};
+struct hfa_dldx3_t hfa_dldx3 = {123456.7890dl, 234567.8901dl, 345678.9012dl};
+struct non_hfa_dfx5_t non_hfa_dfx5 = {456.789df, 567.890df, 678.901df, 789.012df, 890.123df};
+struct hfa_dffs_t hfa_dffs;
+struct non_hfa_dffs_t non_hfa_dffs;
+struct non_hfa_dffs_2_t non_hfa_dffs_2;
+struct hva_vdf2x1_t hva_vdf2x1;
+struct non_hfa_dffd_t non_hfa_dffd = {23.df, 24.df, 25.0dd};
+struct non_hfa_dffvf2_t non_hfa_dffvf2;
+struct non_hfa_dfffd_t non_hfa_dfffd = {33.df, 34.df, 35.df, 36.0dd};
+union hfa_dunion_t hfa_dunion;
+union non_hfa_dunion_t non_hfa_dunion;
+
 #define HAS_DATA_INIT_FUNC
 void init_data ()
 {
@@ -61,6 +78,36 @@ void init_data ()
   non_hfa_ffs_2.s.b = 51;
   non_hfa_ffs_2.c = 52.f;
   non_hfa_ffs_2.d = 53.f;
+
+  /* Decimal floating-point.  */
+  hva_vdf2x1.a = (vdf2_t){17.df, 18.df};
+
+  non_hfa_dffvf2.a = 29.df;
+  non_hfa_dffvf2.b = 30.df;
+  non_hfa_dffvf2.c = (vdf2_t){31.df, 32.df};
+
+  hfa_dunion.s.a = 37.df;
+  hfa_dunion.s.b = 38.df;
+  hfa_dunion.c   = 39.df;
+
+  non_hfa_dunion.a = 40.0dd;
+  non_hfa_dunion.b = 41.df;
+
+  hfa_dffs.a = 42.df;
+  hfa_dffs.b = 43.df;
+  hfa_dffs.c.a = 44.df;
+  hfa_dffs.c.b = 45.df;
+
+  non_hfa_dffs.a = 46.df;
+  non_hfa_dffs.b = 47.df;
+  non_hfa_dffs.c.a = 48.0dd;
+  non_hfa_dffs.c.b = 49.0dd;
+
+  non_hfa_dffs_2.s.a = 50;
+  non_hfa_dffs_2.s.b = 51;
+  non_hfa_dffs_2.c = 52.df;
+  non_hfa_dffs_2.d = 53.df;
+
 }
 
 #include "abitest-2.h"
@@ -90,4 +137,24 @@ FUNC_VAL_CHECK (18, struct non_hfa_ffs_t  , non_hfa_ffs  , X8, flat)
 FUNC_VAL_CHECK (19, struct non_hfa_ffs_2_t, non_hfa_ffs_2, X0, flat)
 FUNC_VAL_CHECK (20, union  non_hfa_union_t, non_hfa_union, X0, flat)
 
+/* Decimal floating-point.  */
+FUNC_VAL_CHECK (21, struct hfa_dfx1_t , hfa_dfx1  , S0, flat)
+FUNC_VAL_CHECK (22, struct hfa_dfx2_t , hfa_dfx2  , S0, flat)
+FUNC_VAL_CHECK (23, struct hfa_ddx2_t , hfa_ddx2  , D0, flat)
+
+FUNC_VAL_CHECK (24, struct hfa_ddx4_t , hfa_ddx4  , D0, flat)
+FUNC_VAL_CHECK (25, struct hfa_dldx3_t, hfa_dldx3 , Q0, flat)
+FUNC_VAL_CHECK (26, struct hfa_dffs_t , hfa_dffs  , S0, flat)
+FUNC_VAL_CHECK (27, union hfa_dunion_t, hfa_dunion, S0, flat)
+
+FUNC_VAL_CHECK (28, struct hva_vdf2x1_t, hva_vdf2x1, D0, flat)
+
+FUNC_VAL_CHECK (29, struct non_hfa_dfx5_t  , non_hfa_dfx5  , X8, flat)
+FUNC_VAL_CHECK (30, struct non_hfa_dffd_t  , non_hfa_dffd  , X0, flat)
+FUNC_VAL_CHECK (31, struct non_hfa_dffvf2_t, non_hfa_dffvf2, X0, flat)
+FUNC_VAL_CHECK (32, struct non_hfa_dfffd_t , non_hfa_dfffd , X8, flat)
+FUNC_VAL_CHECK (33, struct non_hfa_dffs_t  , non_hfa_dffs  , X8, flat)
+FUNC_VAL_CHECK (34, struct non_hfa_dffs_2_t, non_hfa_dffs_2, X0, flat)
+FUNC_VAL_CHECK (35, union  non_hfa_dunion_t, non_hfa_dunion, X0, flat)
+
 #endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_dfp_5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_dfp_5.c
new file mode 100644
index 00000000000..4d0fdd9bc39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_dfp_5.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+
+struct S
+{
+  union
+    {
+      _Decimal128 b;
+    } a;
+};
+
+struct S s;
+
+extern struct S a[5];
+extern struct S check (struct S, struct S *, struct S);
+extern void checkx (struct S);
+
+void test (void)
+{
+  checkx (check (s, &a[1], a[2]));
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align_dfp-1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align_dfp-1.c
new file mode 100644
index 00000000000..35913e9f2d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align_dfp-1.c
@@ -0,0 +1,126 @@
+/* Test AAPCS64 layout.
+
+   Test the comformance to the alignment and padding requirements.
+
+   B.4  If the argument type is a Composite Type then the size of the
+        argument is rounded up to the nearest multiple of 8 bytes.
+   C.4  If the argument is an HFA, a Quad-precision Floating-point or Short
+	Vector Type then the NSAA is rounded up to the larger of 8 or the
+	Natural Alignment of the argument's type.
+   C.12 The NSAA is rounded up to the larger of 8 or the Natural Alignment
+	of the argument's type.
+   C.14 If the size of the argument is less than 8 bytes then the size of
+	the argument is set ot 8 bytes.  The effect is as if the argument
+	was copied to the least significant bits of a 64-bit register and
+	the remaining bits filled with unspecified values.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align-1.c"
+#include "type-def.h"
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+};
+
+struct y v1 = { 1, 2, 3, 4 };
+struct y v2 = { 5, 6, 7, 8 };
+struct y v3 = { 9, 10, 11, 12 };
+struct y v4 = { 13, 14, 15, 16 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+vf4_t c = { 13.f, 14.f, 15.f, 16.f };
+
+struct x
+{
+  vf4_t v;
+} w;
+
+char ch='a';
+short sh=13;
+int i=14;
+long long ll=15;
+
+struct s1
+{
+  short sh[3];
+} s1;
+
+struct s2
+{
+  int i[2];
+  char c;
+} s2;
+
+struct ldx2_t
+{
+  _Decimal128 ld[2];
+} ldx2 = { 12345.67890dl, 23456.78901dl };
+
+union u_t
+{
+  _Decimal128 ld;
+  _Decimal64 d[2];
+} u;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  w.v = (vf4_t){ 17.f, 18.f, 19.f, 20.f };
+  s1.sh[0] = 16;
+  s1.sh[1] = 17;
+  s1.sh[2] = 18;
+  s2.i[0] = 19;
+  s2.i[1] = 20;
+  s2.c = 21;
+  u.ld = 34567.89012L;
+}
+
+#include "abitest.h"
+#else
+
+  ARG(struct y, v1, X0)
+  ARG(struct y, v2, X2)
+  ARG(struct y, v3, X4)
+  ARG(struct y, v4, X6)
+  ARG(struct z, a, D0)
+  ARG(struct z, b, D4)
+  ARG(_Decimal64, 12.5, STACK)
+  ARG(vf4_t, c, STACK+16)       /* [C.4] 16-byte aligned short vector */
+  ARG(_Decimal64, 17.0dd, STACK+32)
+  ARG(struct x, w, STACK+48)    /* [C.12] 16-byte aligned small struct */
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ARG(char, ch, STACK+64)       /* [C.14] char  padded to the size of 8 bytes */
+  ARG(short, sh, STACK+72)      /* [C.14] short padded to the size of 8 bytes */
+  ARG(int, i, STACK+80)         /* [C.14] int   padded to the size of 8 bytes */
+#else
+  ARG(char, ch, STACK+71)
+  ARG(short, sh, STACK+78)
+  ARG(int, i, STACK+84)
+#endif
+  ARG(long long, ll, STACK+88)
+  ARG(struct s1, s1, STACK+96)  /* [B.4] small struct padded to the size of 8 bytes */
+  ARG(_Decimal64, 18.0dd, STACK+104)
+  ARG(struct s2, s2, STACK+112) /* [B.4] small struct padded to the size of 16 bytes */
+  ARG(_Decimal64, 19.0dd, STACK+128)
+  ARG(_Decimal128, 30.0dl, STACK+144)  /* [C.4] 16-byte aligned quad-precision */
+  ARG(_Decimal64, 31.0dd, STACK+160)
+  ARG(struct ldx2_t, ldx2, STACK+176) /* [C.4] 16-byte aligned HFA */
+  ARG(_Decimal64, 32.0dd, STACK+208)
+  ARG(__int128, 33, STACK+224)  /* [C.12] 16-byte aligned 128-bit integer */
+  ARG(_Decimal64, 34.0dd, STACK+240)
+  ARG(union u_t, u, STACK+256)  /* [C.12] 16-byte aligned small composite (union in this case) */
+  LAST_ARG_NONFLAT (int, 35.0, STACK+272, i32in64)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align_dfp-4.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align_dfp-4.c
new file mode 100644
index 00000000000..50ee7c0cc9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_align_dfp-4.c
@@ -0,0 +1,42 @@
+/* Test AAPCS64 layout.
+
+   C.3 If the argument is an HFA then the NSRN is set to 8 and the size
+   of the argument is rounded up to the nearest multiple of 8 bytes.
+
+   TODO: add the check of an HFA containing half-precision floating-point
+   when __f16 is supported in A64 GCC.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_align_dfp-4.c"
+
+struct z1
+{
+  _Decimal64 x[4];
+};
+
+struct z1 a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+
+struct z2
+{
+  _Decimal32 x[3];
+};
+
+struct z2 b = { 13.df, 14.df, 15.df };
+struct z2 c = { 16.df, 17.df, 18.df };
+
+#include "abitest.h"
+#else
+
+  ARG(struct z1, a, D0)
+  ARG(_Decimal64, 9.0dd, D4)
+  ARG(_Decimal64, 10.0dd, D5)
+  ARG(struct z2, b, STACK)       /* [C.3] on stack and size padded to 16 bytes */
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ARG(_Decimal32, 15.5df, STACK+16)    /* [C.3] NSRN has been set to 8 */
+#else
+  ARG(_Decimal32, 15.5df, STACK+20)
+#endif
+  LAST_ARG(struct z2, c, STACK+24)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_1.c
new file mode 100644
index 00000000000..3435261b07d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_1.c
@@ -0,0 +1,31 @@
+/* Test AAPCS64 layout */
+
+/* C.7  If the argument is an Integral Type, the size of the argument is
+	less than or equal to 8 bytes and the NGRN is less than 8, the
+	argument is copied to the least significant bits in x[NGRN].  The
+	NGRN is incremented by one.  The argument has now been allocated.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_1.c"
+/* TODO: review if we need this */
+#define RUNTIME_ENDIANNESS_CHECK
+#include "abitest.h"
+#else
+  ARG(int, 4, W0)
+  ARG(_Decimal64, 4.0dd, D0)
+  ARG(int, 3, W1)
+  /* TODO: review the way of memcpy char, short, etc.  */
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ARG(char, 0xEF, X2)
+  ARG(short, 0xBEEF, X3)
+  ARG(int, 0xDEADBEEF, X4)
+#else
+  /* TODO: need the model/qemu to be big-endian as well  */
+  ARG(char, 0xEF, X2+7)
+  ARG(short, 0xBEEF, X3+6)
+  ARG(int, 0xDEADBEEF, X4+4)
+#endif
+  LAST_ARG(long long, 0xDEADBEEFCAFEBABELL, X5)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_10.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_10.c
new file mode 100644
index 00000000000..8c1ccd1e7ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_10.c
@@ -0,0 +1,26 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_10.c"
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+
+  ARG(int, 7, W0)
+  DOTS
+  ANON(struct z, a, D0)
+  ANON(struct z, b, D4)
+  ANON(_Decimal64, 0.5dd, STACK)
+  LAST_ANON(_Decimal64, 1.5dd, STACK+8)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_11.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_11.c
new file mode 100644
index 00000000000..d06de66cc17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_11.c
@@ -0,0 +1,34 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_11.c"
+
+__complex__ x = 1.0+2.0i;
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(_Decimal64, 11.0dd, D0)
+  DOTS
+  ANON(struct z, a, D1)
+  ANON(struct z, b, STACK)
+  LAST_ANON(_Decimal64, 0.5dd, STACK+32)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_12.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_12.c
new file mode 100644
index 00000000000..491bfd9964e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_12.c
@@ -0,0 +1,44 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_12.c"
+
+
+struct y
+{
+  long p;
+  long q;
+  long r;
+  long s;
+} v = { 1, 2, 3, 4 };
+
+struct y1
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v1 = { 1, 2, 3, 4 };
+
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#define MYFUNCTYPE struct y
+
+#include "abitest.h"
+#else
+  ARG(int, 7, W0)
+  ARG(struct y1, v1, X1)
+  ARG(struct z, a, D0)
+  ARG(struct z, b, D4)
+  LAST_ARG(_Decimal64, 0.5dd, STACK)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_13.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_13.c
new file mode 100644
index 00000000000..6012185285b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_13.c
@@ -0,0 +1,34 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+
+#define TESTFILE "test_dfp_13.c"
+
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(int, 7, W0)
+  ARG(struct y, v, X1)
+  ARG(struct z, a, D0)
+  ARG(_Decimal64, 1.0dd, D4)
+  ARG(struct z, b, STACK)
+  LAST_ARG(_Decimal64, 0.5dd, STACK+32)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_14.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_14.c
new file mode 100644
index 00000000000..9d1cf2d94d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_14.c
@@ -0,0 +1,35 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_14.c"
+
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(int, 7, W0)
+  ARG(int, 9, W1)
+  ARG(struct z, a, D0)
+  ARG(_Decimal64, 1.0dd, D4)
+  ARG(struct z, b, STACK)
+  ARG(int, 4, W2)
+  LAST_ARG(_Decimal64, 0.5dd, STACK+32)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_15.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_15.c
new file mode 100644
index 00000000000..8ec7b4662a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_15.c
@@ -0,0 +1,21 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_15.c"
+
+#include "abitest.h"
+#else
+  ARG(_Decimal64, 1.0dd, D0)
+  ARG(_Decimal64, 2.0dd, D1)
+  ARG(_Decimal64, 3.0dd, D2)
+  ARG(_Decimal64, 4.0dd, D3)
+  ARG(_Decimal64, 5.0dd, D4)
+  ARG(_Decimal64, 6.0dd, D5)
+  ARG(_Decimal64, 7.0dd, D6)
+  ARG(_Decimal64, 8.0dd, D7)
+  ARG(_Decimal64, 9.0dd, STACK)
+  LAST_ARG(_Decimal64, 10.0dd, STACK+8)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_16.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_16.c
new file mode 100644
index 00000000000..cdbfd96c475
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_16.c
@@ -0,0 +1,32 @@
+/* Test AAPCS layout */
+/* C.5 If the argument is a Half- or Single- precision Floating-point type,
+   then the size of the argument is set to 8 bytes.  The effect is as if
+   the argument had been copied to the least significant bits of a 64-bit
+   register and the remaining bits filled with unspecified values.  */
+/* TODO: add the check of half-precision floating-point when it is supported
+   by the A64 GCC.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_16.c"
+
+#include "abitest.h"
+#else
+  ARG(_Decimal32, 1.0df, S0)
+  ARG(_Decimal32, 2.0df, S1)
+  ARG(_Decimal32, 3.0df, S2)
+  ARG(_Decimal32, 4.0df, S3)
+  ARG(_Decimal32, 5.0df, S4)
+  ARG(_Decimal32, 6.0df, S5)
+  ARG(_Decimal32, 7.0df, S6)
+  ARG(_Decimal32, 8.0df, S7)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ARG(_Decimal32, 9.0df, STACK)
+  LAST_ARG(_Decimal32, 10.0df, STACK+8)
+#else
+  ARG(_Decimal32, 9.0df, STACK+4)
+  LAST_ARG(_Decimal32, 10.0df, STACK+12)
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c
new file mode 100644
index 00000000000..22dc462bf7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_17.c
@@ -0,0 +1,37 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_17.c"
+
+__complex__ x = 1.0+2.0i;
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+_Decimal32 f1 = 25.0df;
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(_Decimal64, 11.0dd, D0)
+  DOTS
+  ANON(struct z, a, D1)
+  ANON(struct z, b, STACK)
+  ANON(int , 5, W0)
+  ANON(_Decimal32, f1, STACK+32) /* Note: no promotion to _Decimal64.  */
+  LAST_ANON(_Decimal64, 0.5dd, STACK+40)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_18.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_18.c
new file mode 100644
index 00000000000..bb90b0c906f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_18.c
@@ -0,0 +1,34 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+
+#define TESTFILE "test_dfp_18.c"
+
+
+struct y
+{
+  long long p;
+  long long q;
+  long long r;
+  long long s;
+} v = { 1, 2, 3, 4 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(int, 7, W0)
+  PTR(struct y, v, X1)
+  ARG(struct z, a, D0)
+  ARG(_Decimal64, 1.0dd, D4)
+  ARG(struct z, b, STACK)
+  LAST_ARG(_Decimal64, 0.5dd, STACK+32)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_19.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_19.c
new file mode 100644
index 00000000000..e8210ec3c93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_19.c
@@ -0,0 +1,35 @@
+/* Test AAPCS64 layout.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_19.c"
+
+struct y
+{
+  int p1;
+  int p2;
+  _Decimal32 q;
+  int r1;
+  int r2;
+  char x;
+} v = { -1, 1, 2.0df, 3, 18, 19, 20};
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(int, 7, W0)
+  DOTS
+  ANON(_Decimal64, 4.0dd, D0)
+  ANON(struct z, a, D1)
+  ANON(struct z, b, STACK)
+  PTR_ANON(struct y, v, X1)
+  LAST_ANON(int, 10, W2)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_2.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_2.c
new file mode 100644
index 00000000000..5e9716cdb0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_2.c
@@ -0,0 +1,17 @@
+/* Test AAPCS64 layout */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_2.c"
+#include "abitest.h"
+
+#else
+  ARG(_Decimal32, 1.0df, S0)
+  ARG(_Decimal64, 4.0dd, D1)
+  ARG(_Decimal32, 2.0df, S2)
+  ARG(_Decimal64, 5.0dd, D3)
+  ARG(__fp16, 8.0f, H4)
+  LAST_ARG(int, 3, W0)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_20.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_20.c
new file mode 100644
index 00000000000..4c524b18dbe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_20.c
@@ -0,0 +1,22 @@
+/* Test AAPCS64 layout */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_20.c"
+
+#include "abitest.h"
+
+#else
+  ARG(int, 8, W0)
+  ARG(_Decimal64, 1.0dd, D0)
+  ARG(_Decimal64, 2.0dd, D1)
+  ARG(_Decimal64, 3.0dd, D2)
+  ARG(_Decimal64, 4.0dd, D3)
+  ARG(_Decimal64, 5.0dd, D4)
+  ARG(_Decimal64, 6.0dd, D5)
+  ARG(_Decimal64, 7.0dd, D6)
+  DOTS
+  ANON(_Complex double, 1234.0 + 567.0i, STACK)
+  LAST_ANON(_Decimal64, -987.0dd, STACK+16)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_21.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_21.c
new file mode 100644
index 00000000000..37c4177d9b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_21.c
@@ -0,0 +1,21 @@
+/* Test AAPCS64 layout */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_21.c"
+
+#include "abitest.h"
+
+#else
+  ARG(int, 8, W0)
+  ARG(_Decimal64, 1.0dd, D0)
+  ARG(_Decimal64, 2.0dd, D1)
+  ARG(_Decimal64, 3.0dd, D2)
+  ARG(_Decimal64, 4.0dd, D3)
+  ARG(_Decimal64, 5.0dd, D4)
+  ARG(_Decimal64, 6.0dd, D5)
+  ARG(_Decimal64, 7.0dd, D6)
+  ARG(_Complex double, 1234.0 + 567.0i, STACK)
+  LAST_ARG(_Decimal64, -987.0dd, STACK+16)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_22.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_22.c
new file mode 100644
index 00000000000..497566836a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_22.c
@@ -0,0 +1,19 @@
+/* Test AAPCS64 layout */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_22.c"
+
+struct y
+{
+  _Decimal32 p;
+  _Decimal32 q;
+} v = { 345.0df, 678.0df };
+
+#include "abitest.h"
+#else
+  ARG(_Decimal32, 123.0df, S0)
+  ARG(struct y, v, S1)
+  LAST_ARG(_Decimal32, 901.0df, S3)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_23.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_23.c
new file mode 100644
index 00000000000..82e72192c3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_23.c
@@ -0,0 +1,42 @@
+/* Test AAPCS64 layout.
+
+   Larger than machine-supported vector size.  The behavior is unspecified by
+   the AAPCS64 document; the implementation opts for pass by reference.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_23.c"
+
+typedef char A __attribute__ ((vector_size (64)));
+
+struct y
+{
+  _Decimal64 df[8];
+};
+
+union u
+{
+  struct y x;
+  A a;
+} u;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  u.x.df[0] = 1.0dd;
+  u.x.df[1] = 2.0dd;
+  u.x.df[2] = 3.0dd;
+  u.x.df[3] = 4.0dd;
+  u.x.df[4] = 5.0dd;
+  u.x.df[5] = 6.0dd;
+  u.x.df[6] = 7.0dd;
+  u.x.df[7] = 8.0dd;
+}
+
+#include "abitest.h"
+#else
+ARG (_Decimal32, 123.0df, S0)
+PTR (A, u.a, X0)
+LAST_ARG_NONFLAT (int, 0xdeadbeef, X1, i32in64)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_24.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_24.c
new file mode 100644
index 00000000000..0b76c9de8c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_24.c
@@ -0,0 +1,22 @@
+/* Test AAPCS64 layout.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_24.c"
+
+typedef _Decimal128 TDtype;
+
+#include "abitest.h"
+#else
+  ARG(TDtype, 1.0dl, Q0)
+  ARG(TDtype, 2.0dl, Q1)
+  ARG(TDtype, 3.0dl, Q2)
+  ARG(TDtype, 4.0dl, Q3)
+  ARG(TDtype, 5.0dl, Q4)
+  ARG(TDtype, 6.0dl, Q5)
+  ARG(TDtype, 7.0dl, Q6)
+  ARG(TDtype, 8.0dl, Q7)
+  ARG(_Decimal64, 9.0dd, STACK)
+  LAST_ARG(TDtype, 10.0dl, STACK+16)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_25.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_25.c
new file mode 100644
index 00000000000..04372adc1e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_25.c
@@ -0,0 +1,61 @@
+/* Test AAPCS64 layout
+
+   Test homogeneous floating-point aggregates and homogeneous short-vector
+   aggregates, which should be passed in SIMD/FP registers or via the
+   stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_25.c"
+
+typedef _Decimal32 vf2_t __attribute__((vector_size (8)));
+struct x0
+{
+  vf2_t v;
+} s0;
+struct x3
+{
+  vf2_t v[2];
+} s3;
+struct x4
+{
+  vf2_t v[3];
+} s4;
+
+typedef _Decimal32 vf4_t __attribute__((vector_size(16)));
+struct x1
+{
+  vf4_t v;
+} s1;
+
+struct x2
+{
+  _Decimal64 df[3];
+} s2;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  s0.v = (vf2_t){ 17.df, 18.df };
+  s1.v = (vf4_t){ 567.890df, 678.901df, 789.012df, 890.123df };
+  s2.df[0] = 123.456dd;
+  s2.df[1] = 234.567dd;
+  s2.df[2] = 345.678dd;
+  s3.v[0] = (vf2_t){ 19.df, 20.df };
+  s3.v[1] = (vf2_t){ 23.df, 24.df };
+  s4.v[0] = (vf2_t){ 27.df, 28.df };
+  s4.v[1] = (vf2_t){ 31.df, 32.df };
+  s4.v[2] = (vf2_t){ 35.df, 36.df };
+}
+
+#include "abitest.h"
+#else
+ARG (struct x0, s0, D0)
+ARG (struct x2, s2, D1)
+ARG (struct x1, s1, Q4)
+ARG (struct x3, s3, D5)
+ARG (struct x4, s4, STACK)
+ARG (int, 0xdeadbeef, W0)
+LAST_ARG (_Decimal64, 456.789dd, STACK+24)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_26.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_26.c
new file mode 100644
index 00000000000..e95175bfe78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_26.c
@@ -0,0 +1,54 @@
+/* Test AAPCS64 layout.
+
+   Test some small structures that should be passed in GPRs.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_26.c"
+
+struct y0
+{
+  char ch;
+} c0 = { 'A' };
+
+struct y2
+{
+  long long ll[2];
+} c2 = { 0xDEADBEEF, 0xCAFEBABE };
+
+struct y3
+{
+  int i[3];
+} c3 = { 56789, 67890, 78901 };
+
+typedef _Decimal32 vf2_t __attribute__((vector_size (8)));
+struct x0
+{
+  vf2_t v;
+} s0;
+
+typedef short vh4_t __attribute__((vector_size (8)));
+
+struct x1
+{
+  vh4_t v[2];
+} s1;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  s0.v = (vf2_t){ 17.df, 18.df };
+  s1.v[0] = (vh4_t){ 345, 456, 567, 678 };
+  s1.v[1] = (vh4_t){ 789, 890, 901, 123 };
+}
+
+#include "abitest.h"
+#else
+ARG (struct y0, c0, X0)
+ARG (struct y2, c2, X1)
+ARG (struct y3, c3, X3)
+ARG_NONFLAT (struct x0, s0, D0, f32in64)
+ARG (struct x1, s1, D1)
+LAST_ARG_NONFLAT (int, 89012, X5, i32in64)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_27.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_27.c
new file mode 100644
index 00000000000..12dfe7ed12c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_27.c
@@ -0,0 +1,46 @@
+/* Test AAPCS64 layout
+
+   Test named homogeneous floating-point aggregates of __fp16 data,
+   which should be passed in SIMD/FP registers or via the stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_27.c"
+
+struct x0
+{
+  __fp16 v[1];
+} f16x1;
+
+struct x1
+{
+  __fp16 v[2];
+} f16x2;
+
+struct x2
+{
+  __fp16 v[3];
+} f16x3;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  f16x1.v[0] = 2.0f;
+  f16x2.v[0] = 4.0f;
+  f16x2.v[1] = 8.0f;
+  f16x3.v[0] = 16.0f;
+  f16x3.v[1] = 32.0f;
+  f16x3.v[2] = 64.0f;
+}
+
+#include "abitest.h"
+#else
+ARG (struct x0, f16x1, H0)
+ARG (struct x1, f16x2, H1)
+ARG (struct x2, f16x3, H3)
+ARG (struct x1, f16x2, H6)
+ARG (struct x0, f16x1, STACK)
+ARG (int, 0xdeadbeef, W0)
+LAST_ARG (_Decimal64, 456.789dd, STACK+8)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_3.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_3.c
new file mode 100644
index 00000000000..c92cb143cda
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_3.c
@@ -0,0 +1,18 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_3.c"
+
+__complex__ x = 1.0+2.0i;
+
+#include "abitest.h"
+#else
+ARG (_Decimal32, 1.0df, S0)
+ARG (__complex__ double, x, D1)
+ARG (_Decimal32, 2.0df, S3)
+ARG (_Decimal64, 5.0dd, D4)
+LAST_ARG_NONFLAT (int, 3, X0, i32in64)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_5.c
new file mode 100644
index 00000000000..90b30310b74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_5.c
@@ -0,0 +1,24 @@
+/* Test AAPCS64 layout */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_5.c"
+
+__complex__ float x = 1.0+2.0i;
+
+struct y
+{
+  long p;
+  long q;
+} v = { 1, 2};
+
+#include "abitest.h"
+#else
+  ARG(_Decimal32, 1.0df, S0)
+  ARG(__complex__ float, x, S1)
+  ARG(_Decimal32, 2.0df, S3)
+  ARG(_Decimal64, 5.0dd, D4)
+  LAST_ARG(struct y, v, X0)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_6.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_6.c
new file mode 100644
index 00000000000..7c720c6ee69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_6.c
@@ -0,0 +1,26 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_6.c"
+
+__complex__ double x = 1.0+2.0i;
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 };
+
+#include "abitest.h"
+#else
+  ARG(struct y, v, X0)
+  ARG(_Decimal32, 1.0df, S0)
+  ARG(__complex__ double, x, D1)
+  ARG(_Decimal32, 2.0df, S3)
+  ARG(_Decimal64, 5.0dd, D4)
+  LAST_ARG(int, 3, W2)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_7.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_7.c
new file mode 100644
index 00000000000..c53e192e704
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_7.c
@@ -0,0 +1,30 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_dfp_7.c"
+
+__complex__ float x = 1.0f + 2.0i;
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 }, v1 = {5, 6, 7, 8}, v2 = {9, 10, 11, 12};
+
+#include "abitest.h"
+#else
+ARG (struct y, v, X0)
+ARG (struct y, v1, X2)
+ARG (struct y, v2, X4)
+ARG (int, 4, W6)
+ARG (_Decimal32, 1.0df, S0)
+ARG (__complex__ float, x, S1)
+ARG (_Decimal32, 2.0df, S3)
+ARG (_Decimal64, 5.0dd, D4)
+ARG (int, 3, W7)
+LAST_ARG_NONFLAT (int, 5, STACK, i32in64)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_8.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_8.c
new file mode 100644
index 00000000000..2f48918f8c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_8.c
@@ -0,0 +1,24 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_8.c"
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(struct z, a, D0)
+  ARG(struct z, b, D4)
+  ARG(_Decimal64, 0.5dd, STACK)
+  ARG(int, 7, W0)
+  LAST_ARG(int, 8, W1) 
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_9.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_9.c
new file mode 100644
index 00000000000..cf080272096
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_dfp_9.c
@@ -0,0 +1,32 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_dfp_9.c"
+
+struct y
+{
+  int p;
+  int q;
+  int r;
+  int s;
+} v = { 1, 2, 3, 4 };
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(int, 7, W0)
+  ARG(struct y, v, X1)
+  ARG(struct z, a, D0)
+  ARG(struct z, b, D4)
+  LAST_ARG(_Decimal64, 0.5dd, STACK)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/test_quad_double_dfp.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_quad_double_dfp.c
new file mode 100644
index 00000000000..08d540dccf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/test_quad_double_dfp.c
@@ -0,0 +1,26 @@
+/* Test AAPCS64 layout.
+
+   Test parameter passing of floating-point quad precision types.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "test_quad_double_dfp.c"
+
+typedef _Decimal128 TDtype;
+typedef _Complex long double CTFtype;
+
+TDtype x = 1.0dl;
+TDtype y = 2.0dl;
+
+CTFtype cx = 3.0 + 4.0i;
+CTFtype cy = 5.0 + 6.0i;
+
+#include "abitest.h"
+#else
+  ARG       ( TDtype,  x, Q0)
+  ARG       (CTFtype, cx, Q1)
+  DOTS
+  ANON      (CTFtype, cy, Q3)
+  LAST_ANON ( TDtype,  y, Q5)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h b/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h
index ca1fa5811ff..6452b917788 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h
@@ -13,6 +13,15 @@ typedef int vi4_t __attribute__((vector_size (16)));
 /* 128-bit vector of 1 quad precision float.  */
 typedef long double vlf1_t __attribute__((vector_size (16)));
 
+/* 64-bit vector of 2 decimal floats.  */
+typedef _Decimal32 vdf2_t __attribute__((vector_size (8)));
+
+/* 128-bit vector of 4 decimal floats.  */
+typedef _Decimal32 vdf4_t __attribute__((vector_size (16)));
+
+/* 128-bit vector of 1 quad precision decimal float.  */
+typedef _Decimal128 vldf1_t __attribute__((vector_size (16)));
+
 /* signed quad-word (in an union for the convenience of initialization).  */
 union int128_t
 {
@@ -183,3 +192,126 @@ union non_hfa_union_t
   double a;
   float b;
 };
+
+/* Same, with decimal floating-point types.  */
+struct hfa_dfx1_t
+{
+  _Decimal32 a;
+};
+
+struct hfa_dfx2_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+};
+
+struct hfa_dfx3_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  _Decimal32 c;
+};
+
+struct hfa_ddx2_t
+{
+  _Decimal64 a;
+  _Decimal64 b;
+};
+
+struct hfa_ddx4_t
+{
+  _Decimal64 a;
+  _Decimal64 b;
+  _Decimal64 c;
+  _Decimal64 d;
+};
+
+struct hfa_dldx3_t
+{
+  _Decimal128 a;
+  _Decimal128 b;
+  _Decimal128 c;
+};
+
+struct hfa_dffs_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  struct hfa_dfx2_t c;
+};
+
+union hfa_dunion_t
+{
+  struct
+    {
+      _Decimal32 a;
+      _Decimal32 b;
+    } s;
+  _Decimal32 c;
+};
+
+struct non_hfa_dfx5_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  _Decimal32 c;
+  _Decimal32 d;
+  _Decimal32 e;
+};
+
+struct non_hfa_dffs_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  struct hfa_ddx2_t c;
+};
+
+struct non_hfa_dffs_2_t
+{
+  struct
+    {
+      int a;
+      int b;
+    } s;
+  _Decimal32 c;
+  _Decimal32 d;
+};
+
+struct hva_vdf2x1_t
+{
+  vdf2_t a;
+};
+
+struct hva_vdf2x2_t
+{
+  vdf2_t a;
+  vdf2_t b;
+};
+
+struct non_hfa_dffd_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  _Decimal64 c;
+};
+
+struct non_hfa_dffvf2_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  vdf2_t c;
+};
+
+struct non_hfa_dfffd_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+  _Decimal32 c;
+  _Decimal64 d;
+};
+
+union non_hfa_dunion_t
+{
+  _Decimal64 a;
+  _Decimal32 b;
+};
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-1.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-1.c
new file mode 100644
index 00000000000..81e78c1268e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-1.c
@@ -0,0 +1,60 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test covers fundamental data types as specified in AAPCS64 \S 4.1.
+   It is focused on unnamed parameter passed in registers.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-1.c"
+#include "type-def.h"
+
+vf2_t vf2 = (vf2_t){ 17.f, 18.f };
+vi4_t vi4 = (vi4_t){ 0xdeadbabe, 0xbabecafe, 0xcafebeef, 0xbeefdead };
+union int128_t qword;
+signed char sc = 0xed;
+signed int sc_promoted = 0xffffffed;
+signed short ss = 0xcba9;
+signed int ss_promoted = 0xffffcba9;
+_Decimal32 fp = 65432.12345df;
+_Decimal64 fp_promoted = (_Decimal64)65432.12345df;
+__fp16 fp16 = 2.0f;
+__fp16 fp16_promoted = (double)2.0f;
+
+#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      , 0xff  ,                            W0, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON_PROMOTED(unsigned char     , 0xfe  , unsigned int, 0xfe       , W1,       1)
+  ANON_PROMOTED(  signed char     , sc    ,   signed int, sc_promoted, W2,       2)
+  ANON_PROMOTED(unsigned short    , 0xdcba, unsigned int, 0xdcba     , W3,       3)
+  ANON_PROMOTED(  signed short    , ss    ,   signed int, ss_promoted, W4,       4)
+  ANON         (unsigned int      , 0xdeadbeef,                        W5,       5)
+  ANON         (  signed int      , 0xcafebabe,                        W6,       6)
+  ANON         (unsigned long long, 0xba98765432101234ULL,             X7,       7)
+  ANON         (  signed long long, 0xa987654321012345LL ,             STACK,    8)
+  ANON         (          __int128, qword.i              ,             STACK+16, 9)
+  ANON_PROMOTED(     _Decimal32   , fp    ,    _Decimal64, fp_promoted, D0,      10)
+  ANON         (     _Decimal64   , 9876543.212345dd,                  D1,      11)
+  ANON         (    _Decimal128   , 98765432123456789.987654321dl,     Q2,      12)
+  ANON         (             vf2_t, vf2   ,                            D3,      13)
+  ANON         (             vi4_t, vi4   ,                            Q4,      14)
+  /* 7.2: For unprototyped (i.e. pre- ANSI or K&R C) and variadic functions,
+     in addition to the normal conversions and promotions, arguments of
+     type __fp16 are converted to type double.  */
+  ANON_PROMOTED(            __fp16, fp16  ,     double, fp16_promoted, D5,      15)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  LAST_ANON    (         int      , 0xeeee,                            STACK+32,16)
+#else
+  LAST_ANON    (         int      , 0xeeee,                            STACK+36,16)
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-10.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-10.c
new file mode 100644
index 00000000000..c94f1ce2c09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-10.c
@@ -0,0 +1,29 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   Miscellaneous test: Anonymous arguments passed on the stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-10.c"
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+_Decimal64 d1 = 25.0dd;
+_Decimal64 d2 = 103.0dd;
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(struct z, a, D0, 0)
+  ARG(struct z, b, D4, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON(_Decimal64, d1, STACK, 2)
+  LAST_ANON(_Decimal64, d2, STACK+8, 3)
+
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-11.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-11.c
new file mode 100644
index 00000000000..9ca991138dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-11.c
@@ -0,0 +1,32 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   Miscellaneous test: Anonymous arguments passed on the stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-11.c"
+
+struct z
+{
+  _Decimal64 x[2];
+};
+
+_Decimal64 d1 = 25.0dd;
+struct z a = { 5.0dd, 6.0dd };
+
+#include "abitest.h"
+#else
+  ARG(_Decimal64, 1.0dd, D0, 0)
+  ARG(_Decimal64, 2.0dd, D1, 1)
+  ARG(_Decimal64, 3.0dd, D2, 2)
+  ARG(_Decimal64, 4.0dd, D3, 3)
+  ARG(_Decimal64, 5.0dd, D4, 4)
+  ARG(_Decimal64, 6.0dd, D5, 5)
+  ARG(_Decimal64, 7.0dd, D6, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON(struct z, a, STACK, 8)
+  LAST_ANON(_Decimal64, d1, STACK+16, 9)
+
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-12.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-12.c
new file mode 100644
index 00000000000..8e7942f48fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-12.c
@@ -0,0 +1,64 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   Pass by reference.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-12.c"
+
+struct z
+{
+  char c;
+  short s;
+  int ia[4];
+};
+
+struct z a, b, c;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  a.c = 0x11;
+  a.s = 0x2222;
+  a.ia[0] = 0x33333333;
+  a.ia[1] = 0x44444444;
+  a.ia[2] = 0x55555555;
+  a.ia[3] = 0x66666666;
+
+  b.c = 0x77;
+  b.s = 0x8888;
+  b.ia[0] = 0x99999999;
+  b.ia[1] = 0xaaaaaaaa;
+  b.ia[2] = 0xbbbbbbbb;
+  b.ia[3] = 0xcccccccc;
+
+  c.c = 0xdd;
+  c.s = 0xeeee;
+  c.ia[0] = 0xffffffff;
+  c.ia[1] = 0x12121212;
+  c.ia[2] = 0x23232323;
+  c.ia[3] = 0x34343434;
+}
+
+#include "abitest.h"
+#else
+  PTR(struct z, a, X0, 0)
+  ARG(int, 0xdeadbeef, W1, 1)
+  ARG(int, 0xcafebabe, W2, 2)
+  ARG(int, 0xdeadbabe, W3, 3)
+  ARG(int, 0xcafebeef, W4, 4)
+  ARG(int, 0xbeefdead, W5, 5)
+  ARG(int, 0xbabecafe, W6, LAST_NAMED_ARG_ID)
+  DOTS
+  PTR_ANON(struct z, b, X7, 7)
+  PTR_ANON(struct z, c, STACK, 8)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ANON(int, 0xbabedead, STACK+8, 9)
+#else
+  ANON(int, 0xbabedead, STACK+12, 9)
+#endif
+  LAST_ANON(_Decimal64, 123.45dd, D0, 10)
+
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-13.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-13.c
new file mode 100644
index 00000000000..59d5d5ebd6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-13.c
@@ -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_dfp-13.c"
+
+struct float_float_t
+{
+  _Decimal32 a;
+  _Decimal32 b;
+} float_float;
+
+union float_int_t
+{
+  _Decimal32 b8;
+  int b5;
+} float_int;
+
+#define HAS_DATA_INIT_FUNC
+void
+init_data ()
+{
+  float_float.a = 1.2df;
+  float_float.b = 2.2df;
+
+  float_int.b8 = 4983.80df;
+}
+
+#include "abitest.h"
+#else
+  ARG (_Decimal32, 1.0df, S0, 0)
+  ARG (_Decimal32, 2.0df, S1, 1)
+  ARG (_Decimal32, 3.0df, S2, 2)
+  ARG (_Decimal32, 4.0df, S3, 3)
+  ARG (_Decimal32, 5.0df, S4, 4)
+  ARG (_Decimal32, 6.0df, S5, 5)
+  ARG (_Decimal32, 7.0df, 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_dfp-14.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-14.c
new file mode 100644
index 00000000000..b54c66f0115
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-14.c
@@ -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_dfp-14.c"
+#include "type-def.h"
+
+struct hfa_dfx2_t hfa_dfx2 = {1.2df, 2.2df};
+struct hfa_dfx3_t hfa_dfx3 = {3.2df, 4.2df, 5.2df};
+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 (_Decimal32, 1.0df, S0, 0)
+  ARG (_Decimal32, 2.0df, S1, 1)
+  ARG (_Decimal32, 3.0df, S2, 2)
+  ARG (_Decimal32, 4.0df, S3, 3)
+  ARG (_Decimal32, 5.0df, S4, 4)
+  ARG (_Decimal32, 6.0df, S5, 5)
+  ARG (_Decimal32, 7.0df, S6, 6)
+  ARG (struct hfa_dfx3_t, hfa_dfx3, STACK, 7)
+  /* Previous argument size has been rounded up to the nearest multiple of
+     8 bytes.  */
+  ARG (struct hfa_dfx2_t, hfa_dfx2, 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 (_Decimal64, 123456789.987dd, STACK + 64, 11)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-16.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-16.c
new file mode 100644
index 00000000000..5e17e6d273d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-16.c
@@ -0,0 +1,28 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test is focused particularly on __fp16 unnamed homogeneous
+   floating-point aggregate types which should be passed in fp/simd
+   registers until we run out of those, then the stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-16.c"
+#include "type-def.h"
+
+struct hfa_f16x1_t hfa_f16x1 = {2.0f};
+struct hfa_f16x2_t hfa_f16x2 = {4.0f, 8.0f};
+struct hfa_f16x3_t hfa_f16x3 = {16.0f, 32.0f, 64.0f};
+
+#include "abitest.h"
+#else
+  ARG      (int, 1, W0, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON     (struct hfa_f16x1_t, hfa_f16x1, H0     , 0)
+  ANON     (struct hfa_f16x2_t, hfa_f16x2, H1     , 1)
+  ANON     (struct hfa_f16x3_t, hfa_f16x3, H3     , 2)
+  ANON     (struct hfa_f16x2_t, hfa_f16x2, H6     , 3)
+  ANON     (struct hfa_f16x1_t, hfa_f16x1, STACK  , 4)
+  LAST_ANON(_Decimal64        , 1.0dd    , STACK+8, 5)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-2.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-2.c
new file mode 100644
index 00000000000..d14bfb36e1d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-2.c
@@ -0,0 +1,75 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test covers fundamental data types as specified in AAPCS64 \S 4.1.
+   It is focus on unnamed parameter passed on stack.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-2.c"
+#include "type-def.h"
+
+vf2_t vf2 = (vf2_t){ 17.f, 18.f };
+vi4_t vi4 = (vi4_t){ 0xdeadbabe, 0xbabecafe, 0xcafebeef, 0xbeefdead };
+union int128_t qword;
+signed char sc = 0xed;
+signed int sc_promoted = 0xffffffed;
+signed short ss = 0xcba9;
+signed int ss_promoted = 0xffffcba9;
+_Decimal32 fp = 65432.12345df;
+_Decimal64 fp_promoted = (_Decimal64)65432.12345df;
+__fp16 fp16 = 2.0f;
+__fp16 fp16_promoted = (double)2.0f;
+
+#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      , 0xff  ,                            W0,        0)
+  ARG          (    _Decimal32    , 1.0df ,                            S0,        1)
+  ARG          (    _Decimal32    , 1.0df ,                            S1,        2)
+  ARG          (    _Decimal32    , 1.0df ,                            S2,        3)
+  ARG          (    _Decimal32    , 1.0df ,                            S3,        4)
+  ARG          (    _Decimal32    , 1.0df ,                            S4,        5)
+  ARG          (    _Decimal32    , 1.0df ,                            S5,        6)
+  ARG          (    _Decimal32    , 1.0df ,                            S6,        7)
+  ARG          (    _Decimal32    , 1.0df ,                            S7, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON         (          __int128, qword.i              ,             X2,        8)
+  ANON         (  signed long long, 0xa987654321012345LL ,             X4,        9)
+  ANON         (          __int128, qword.i              ,             X6,       10)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ANON_PROMOTED(unsigned char     , 0xfe  , unsigned int, 0xfe       , STACK,    11)
+  ANON_PROMOTED(  signed char     , sc    ,   signed int, sc_promoted, STACK+8,  12)
+  ANON_PROMOTED(unsigned short    , 0xdcba, unsigned int, 0xdcba     , STACK+16, 13)
+  ANON_PROMOTED(  signed short    , ss    ,   signed int, ss_promoted, STACK+24, 14)
+  ANON         (unsigned int      , 0xdeadbeef,                        STACK+32, 15)
+  ANON         (  signed int      , 0xcafebabe,                        STACK+40, 16)
+#else
+  ANON_PROMOTED(unsigned char     , 0xfe  , unsigned int, 0xfe       , STACK+4,  11)
+  ANON_PROMOTED(  signed char     , sc    ,   signed int, sc_promoted, STACK+12, 12)
+  ANON_PROMOTED(unsigned short    , 0xdcba, unsigned int, 0xdcba     , STACK+20, 13)
+  ANON_PROMOTED(  signed short    , ss    ,   signed int, ss_promoted, STACK+28, 14)
+  ANON         (unsigned int      , 0xdeadbeef,                        STACK+36, 15)
+  ANON         (  signed int      , 0xcafebabe,                        STACK+44, 16)
+#endif
+  ANON         (unsigned long long, 0xba98765432101234ULL,             STACK+48, 17)
+  ANON_PROMOTED(    _Decimal32    , fp    ,       _Decimal64, fp_promoted, STACK+56, 18)
+  ANON         (     _Decimal64   , 9876543.212345dd,                  STACK+64, 19)
+  ANON         (    _Decimal128   , 98765432123456789.987654321dl,     STACK+80, 20)
+  ANON         (             vf2_t, vf2   ,                            STACK+96, 21)
+  ANON         (             vi4_t, vi4   ,                            STACK+112,22)
+  ANON_PROMOTED(         __fp16   , fp16  ,     double, fp16_promoted, STACK+128,23)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  LAST_ANON    (         int      , 0xeeee,                            STACK+136,24)
+#else
+  LAST_ANON    (         int      , 0xeeee,                            STACK+140,24)
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-3.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-3.c
new file mode 100644
index 00000000000..9ab386f7a12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-3.c
@@ -0,0 +1,94 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test covers most composite types as described in AAPCS64 \S 4.3.
+   Homogeneous floating-point aggregate types are covered in other tests.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg-3.c"
+#include "type-def.h"
+
+struct x0
+{
+  char ch;
+  int i;
+} y0 = { 'a', 12345 };
+
+struct x1
+{
+  int a;
+  int b;
+  int c;
+  int d;
+} y1 = { 0xdeadbeef, 0xcafebabe, 0x87654321, 0xabcedf975 };
+
+struct x2
+{
+  long long a;
+  long long b;
+  char ch;
+} y2 = { 0x12, 0x34, 0x56 };
+
+union x3
+{
+  char ch;
+  int i;
+  long long ll;
+} y3;
+
+union x4
+{
+  int i;
+  struct x2 y2;
+} y4;
+
+struct x5
+{
+  union int128_t qword;
+} y5;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  /* Init small union.  */
+  y3.ll = 0xfedcba98LL;
+
+  /* Init big union.  */
+  y4.y2.a = 0x78;
+  y4.y2.b = 0x89;
+  y4.y2.ch= 0x9a;
+
+  /* Init signed quad-word integer.  */
+  y5.qword.l64 = 0xfdb9753102468aceLL;
+  y5.qword.h64 = 0xeca8642013579bdfLL;
+}
+
+#include "abitest.h"
+#else
+  ARG      (_Decimal32 ,1.0df, S0, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON     (struct x0, y0, X0,        1)
+  ANON     (struct x1, y1, X1,        2)
+  PTR_ANON (struct x2, y2, X3,        3)
+  ANON     (union  x3, y3, X4,        4)
+  PTR_ANON (union  x4, y4, X5,        5)
+  ANON     (struct x5, y5, X6,        6)
+  ANON     (struct x0, y0, STACK,     7)
+  ANON     (struct x1, y1, STACK+8,   8)
+  PTR_ANON (struct x2, y2, STACK+24,  9)
+  ANON     (union  x3, y3, STACK+32, 10)
+  PTR_ANON (union  x4, y4, STACK+40, 11)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  ANON     (int      ,  1, STACK+48, 12)
+#else
+  ANON     (int      ,  1, STACK+52, 12)
+#endif
+  ANON     (struct x5, y5, STACK+64, 13)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  LAST_ANON(int      ,  2, STACK+80, 14)
+#else
+  LAST_ANON(int      ,  2, STACK+84, 14)
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-4.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-4.c
new file mode 100644
index 00000000000..cf79aaa2c7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-4.c
@@ -0,0 +1,90 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test covers homogeneous floating-point aggregate types and homogeneous
+   short-vector aggregate types as described in AAPCS64 \S 4.3.5.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg-4.c"
+#include "type-def.h"
+
+struct hfa_dfx1_t hfa_dfx1 = {12.345df};
+struct hfa_dfx2_t hfa_dfx2 = {123.456df, 234.456df};
+struct hfa_ddx2_t hfa_ddx2 = {234.567dd, 345.678dd};
+struct hfa_ddx4_t hfa_ddx4 = {1234.123dd, 2345.234dd, 3456.345dd, 4567.456dd};
+struct hfa_dldx3_t hfa_dldx3 = {123456.7890dl, 234567.8901dl, 345678.9012dl};
+struct non_hfa_dfx5_t non_hfa_dfx5 = {456.789df, 567.890df, 678.901df, 789.012df, 890.123df};
+struct hfa_dffs_t hfa_dffs;
+struct non_hfa_dffs_t non_hfa_dffs;
+struct non_hfa_dffs_2_t non_hfa_dffs_2;
+struct hva_vdf2x1_t hva_vdf2x1;
+struct hva_vdf2x2_t hva_vdf2x2;
+struct non_hfa_dffd_t non_hfa_dffd = {23.df, 24.df, 25.0dd};
+struct non_hfa_dffvf2_t non_hfa_dffvf2;
+struct non_hfa_dfffd_t non_hfa_dfffd = {33.df, 34.df, 35.df, 36.0dd};
+union hfa_dunion_t hfa_dunion;
+union non_hfa_union_t non_hfa_union;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  hva_vdf2x1.a = (vdf2_t){17.df, 18.df};
+  hva_vdf2x2.a = (vdf2_t){19.df, 20.df};
+  hva_vdf2x2.b = (vdf2_t){21.df, 22.df};
+
+  non_hfa_dffvf2.a = 29.df;
+  non_hfa_dffvf2.b = 30.df;
+  non_hfa_dffvf2.c = (vdf2_t){31.df, 32.df};
+
+  hfa_dunion.s.a = 37.df;
+  hfa_dunion.s.b = 38.df;
+  hfa_dunion.c   = 39.df;
+
+  non_hfa_dunion.a = 40.0dd;
+  non_hfa_dunion.b = 41.df;
+
+  hfa_dffs.a = 42.df;
+  hfa_dffs.b = 43.df;
+  hfa_dffs.c.a = 44.df;
+  hfa_dffs.c.b = 45.df;
+
+  non_hfa_dffs.a = 46.df;
+  non_hfa_dffs.b = 47.df;
+  non_hfa_dffs.c.a = 48.0dd;
+  non_hfa_dffs.c.b = 49.0dd;
+
+  non_hfa_dffs_2.s.a = 50;
+  non_hfa_dffs_2.s.b = 51;
+  non_hfa_dffs_2.c = 52.df;
+  non_hfa_dffs_2.d = 53.df;
+}
+
+#include "abitest.h"
+#else
+  ARG      (int   , 1, W0, LAST_NAMED_ARG_ID)
+  DOTS
+  /* HFA or HVA passed in fp/simd registers or on stack.  */
+  ANON     (struct hfa_dfx1_t , hfa_dfx1,  S0      , 0)
+  ANON     (struct hfa_dfx2_t , hfa_dfx2,  S1      , 1)
+  ANON     (struct hfa_ddx2_t , hfa_ddx2,  D3      , 2)
+  ANON     (struct hva_vdf2x1_t, hva_vdf2x1, D5      , 11)
+  ANON     (struct hfa_ddx4_t , hfa_ddx4,  STACK   , 3)
+  ANON     (struct hfa_dffs_t , hfa_dffs , STACK+32, 4)
+  ANON     (union  hfa_dunion_t, hfa_dunion, STACK+48, 5)
+  ANON     (struct hfa_dldx3_t, hfa_dldx3, STACK+64, 6)
+  /* Non-H[FV]A passed in general registers or on stack or via reference.  */
+  PTR_ANON (struct non_hfa_dfx5_t , non_hfa_dfx5 , X1       , 10)
+  ANON     (struct non_hfa_dffd_t , non_hfa_dffd , X2       , 13)
+  ANON     (struct non_hfa_dffvf2_t, non_hfa_dffvf2, X6       , 16)
+  PTR_ANON (struct non_hfa_dfffd_t, non_hfa_dfffd, STACK+112, 17)
+  PTR_ANON (struct non_hfa_dffs_t , non_hfa_dffs , STACK+120, 18)
+  ANON     (struct non_hfa_dffs_2_t, non_hfa_dffs_2, STACK+128, 19)
+  ANON     (union  non_hfa_dunion_t, non_hfa_dunion, STACK+144, 20)
+#ifndef __AAPCS64_BIG_ENDIAN__
+  LAST_ANON(int                   , 2            , STACK+152, 30)
+#else
+  LAST_ANON(int                   , 2            , STACK+156, 30)
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-5.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-5.c
new file mode 100644
index 00000000000..57ea87a37d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-5.c
@@ -0,0 +1,47 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test is focus on certain unnamed homogeneous floating-point aggregate
+   types passed in fp/simd registers.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-5.c"
+#include "type-def.h"
+
+struct hfa_dfx1_t hfa_dfx1 = {12.345df};
+struct hfa_dfx2_t hfa_dfx2 = {123.456df, 234.456df};
+struct hfa_ddx2_t hfa_ddx2 = {234.567dd, 345.678dd};
+struct hfa_ddx4_t hfa_ddx4 = {1234.123dd, 2345.234dd, 3456.345dd, 4567.456dd};
+struct hfa_dldx3_t hfa_dldx3 = {123456.7890dl, 234567.8901dl, 345678.9012dl};
+struct hfa_dffs_t hfa_dffs;
+union hfa_dunion_t hfa_dunion;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  hfa_dunion.s.a = 37.df;
+  hfa_dunion.s.b = 38.df;
+  hfa_dunion.c   = 39.df;
+
+  hfa_dffs.a = 42.df;
+  hfa_dffs.b = 43.df;
+  hfa_dffs.c.a = 44.df;
+  hfa_dffs.c.b = 45.df;
+}
+
+#include "abitest.h"
+#else
+  ARG      (int, 1, W0, LAST_NAMED_ARG_ID)
+  DOTS
+  /* HFA passed in fp/simd registers or on stack.  */
+  ANON     (struct hfa_ddx4_t , hfa_ddx4 , D0      , 0)
+  ANON     (struct hfa_dldx3_t, hfa_dldx3, Q4      , 1)
+  ANON     (struct hfa_dffs_t , hfa_dffs , STACK   , 2)
+  ANON     (union  hfa_dunion_t, hfa_dunion, STACK+16, 3)
+  ANON     (struct hfa_dfx1_t , hfa_dfx1 , STACK+24, 4)
+  ANON     (struct hfa_dfx2_t , hfa_dfx2 , STACK+32, 5)
+  ANON     (struct hfa_ddx2_t , hfa_ddx2 , STACK+40, 6)
+  LAST_ANON(_Decimal64        , 1.0dd    , STACK+56, 9)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-6.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-6.c
new file mode 100644
index 00000000000..c4144be3f4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-6.c
@@ -0,0 +1,40 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   This test is focus on certain unnamed homogeneous floating-point aggregate
+   types passed in fp/simd registers.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-6.c"
+#include "type-def.h"
+
+struct hfa_dfx1_t hfa_dfx1 = {12.345df};
+struct hfa_ddx2_t hfa_ddx2 = {234.567dd, 345.678dd};
+struct hfa_dffs_t hfa_dffs;
+union hfa_dunion_t hfa_dunion;
+
+#define HAS_DATA_INIT_FUNC
+void init_data ()
+{
+  hfa_dunion.s.a = 37.df;
+  hfa_dunion.s.b = 38.df;
+  hfa_dunion.c   = 39.df;
+
+  hfa_ffs.a = 42.f;
+  hfa_ffs.b = 43.f;
+  hfa_ffs.c.a = 44.f;
+  hfa_ffs.c.b = 45.f;
+}
+
+#include "abitest.h"
+#else
+  ARG      (int, 1, W0, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON     (struct hfa_dffs_t , hfa_dffs , S0     , 0)
+  ANON     (union  hfa_dunion_t, hfa_dunion, S4   , 1)
+  ANON     (struct hfa_ddx2_t , hfa_ddx2 , D6     , 2)
+  ANON     (struct hfa_dfx1_t , hfa_dfx1 , STACK  , 3)
+  LAST_ANON(_Decimal64        , 1.0dd    , STACK+8, 4)
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-8.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-8.c
new file mode 100644
index 00000000000..bd4562ff9b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-8.c
@@ -0,0 +1,25 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   Miscellaneous test: HFA anonymous parameter passed in SIMD/FP regs.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-8.c"
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+
+#include "abitest.h"
+#else
+  ARG(int, 0xdeadbeef, W0, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON(_Decimal64, 4.0dd, D0, 1)
+  LAST_ANON(struct z, a, D1, 2)
+
+#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-9.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-9.c
new file mode 100644
index 00000000000..d1f95c4ee66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg_dfp-9.c
@@ -0,0 +1,31 @@
+/* Test AAPCS64 layout and __builtin_va_arg.
+
+   Miscellaneous test: HFA anonymous parameter passed in SIMD/FP regs.  */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define AAPCS64_TEST_STDARG
+#define TESTFILE "va_arg_dfp-9.c"
+
+struct z
+{
+  _Decimal64 x[4];
+};
+
+_Decimal64 d1 = 25.0dd;
+struct z a = { 5.0dd, 6.0dd, 7.0dd, 8.0dd };
+struct z b = { 9.0dd, 10.0dd, 11.0dd, 12.0dd };
+
+#include "abitest.h"
+#else
+  ARG(_Decimal64, 11.0dd, D0, LAST_NAMED_ARG_ID)
+  DOTS
+  ANON(int, 8, W0, 1)
+  ANON(struct z, a, D1, 2)
+  ANON(struct z, b, STACK, 3)
+  ANON(int, 5, W1, 4)
+  ANON(_Decimal64, d1, STACK+32, 5)
+  LAST_ANON(_Decimal64, 0.5dd, STACK+40, 6)
+
+#endif
