PR 19051: support of inferior call with gnu vector support on ARM
authorYao Qi <yao.qi@linaro.org>
Fri, 13 Nov 2015 15:11:58 +0000 (15:11 +0000)
committerYao Qi <yao.qi@linaro.org>
Fri, 13 Nov 2015 15:11:58 +0000 (15:11 +0000)
This patch teaches GDB to support gnu vector in inferior calls.  As a
result, fails in gdb.base/gnu_vector.exp are fixed.  The calling
convention of gnu vector isn't documented in the AAPCS, because it
is the GCC extension.  I checked the gcc/config/arm/arm.c, understand
how GCC pass arguments and return values, and do the same in GDB side.

The patch is tested with both hard float and soft float on arm-linux.

gdb:

2015-11-13  Yao Qi  <yao.qi@linaro.org>

PR tdep/19051
* arm-tdep.c (arm_type_align): Return the right alignment
value for vector.
(arm_vfp_cprc_sub_candidate): Return true for 64-bit and
128-bit vector types.
(arm_return_in_memory): Handel vector type.

gdb/ChangeLog
gdb/arm-tdep.c

index a4e73e0ccda67a1e2342f15caef9af6a848dc977..e48ffa1c5c6989a89c9c69a8ac604b1ee291e7db 100644 (file)
@@ -1,3 +1,12 @@
+2015-11-13  Yao Qi  <yao.qi@linaro.org>
+
+       PR tdep/19051
+       * arm-tdep.c (arm_type_align): Return the right alignment
+       value for vector.
+       (arm_vfp_cprc_sub_candidate): Return true for 64-bit and
+       128-bit vector types.
+       (arm_return_in_memory): Handel vector type.
+
 2015-11-13  Yao Qi  <yao.qi@linaro.org>
 
        * arm-tdep.c (arm_return_in_memory): Rewrite it.
index c8b665ab1737154c419acc927f582817736526bf..b8f84ce9d040c9243010bcfb9010b034a2a06361 100644 (file)
@@ -3446,8 +3446,18 @@ arm_type_align (struct type *t)
       return TYPE_LENGTH (t);
 
     case TYPE_CODE_ARRAY:
+      if (TYPE_VECTOR (t))
+       {
+         /* Use the natural alignment for vector types (the same for
+            scalar type), but the maximum alignment is 64-bit.  */
+         if (TYPE_LENGTH (t) > 8)
+           return 8;
+         else
+           return TYPE_LENGTH (t);
+       }
+      else
+       return arm_type_align (TYPE_TARGET_TYPE (t));
     case TYPE_CODE_COMPLEX:
-      /* TODO: What about vector types?  */
       return arm_type_align (TYPE_TARGET_TYPE (t));
 
     case TYPE_CODE_STRUCT:
@@ -3594,21 +3604,44 @@ arm_vfp_cprc_sub_candidate (struct type *t,
 
     case TYPE_CODE_ARRAY:
       {
-       int count;
-       unsigned unitlen;
-       count = arm_vfp_cprc_sub_candidate (TYPE_TARGET_TYPE (t), base_type);
-       if (count == -1)
-         return -1;
-       if (TYPE_LENGTH (t) == 0)
+       if (TYPE_VECTOR (t))
          {
-           gdb_assert (count == 0);
-           return 0;
+           /* A 64-bit or 128-bit containerized vector type are VFP
+              CPRCs.  */
+           switch (TYPE_LENGTH (t))
+             {
+             case 8:
+               if (*base_type == VFP_CPRC_UNKNOWN)
+                 *base_type = VFP_CPRC_VEC64;
+               return 1;
+             case 16:
+               if (*base_type == VFP_CPRC_UNKNOWN)
+                 *base_type = VFP_CPRC_VEC128;
+               return 1;
+             default:
+               return -1;
+             }
+         }
+       else
+         {
+           int count;
+           unsigned unitlen;
+
+           count = arm_vfp_cprc_sub_candidate (TYPE_TARGET_TYPE (t),
+                                               base_type);
+           if (count == -1)
+             return -1;
+           if (TYPE_LENGTH (t) == 0)
+             {
+               gdb_assert (count == 0);
+               return 0;
+             }
+           else if (count == 0)
+             return -1;
+           unitlen = arm_vfp_cprc_unit_length (*base_type);
+           gdb_assert ((TYPE_LENGTH (t) % unitlen) == 0);
+           return TYPE_LENGTH (t) / unitlen;
          }
-       else if (count == 0)
-         return -1;
-       unitlen = arm_vfp_cprc_unit_length (*base_type);
-       gdb_assert ((TYPE_LENGTH (t) % unitlen) == 0);
-       return TYPE_LENGTH (t) / unitlen;
       }
       break;
 
@@ -9000,6 +9033,13 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
       && TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
     return 0;
 
+  if (TYPE_CODE_ARRAY == code && TYPE_VECTOR (type))
+    {
+      /* Vector values should be returned using ARM registers if they
+        are not over 16 bytes.  */
+      return (TYPE_LENGTH (type) > 16);
+    }
+
   if (gdbarch_tdep (gdbarch)->arm_abi != ARM_ABI_APCS)
     {
       /* The AAPCS says all aggregates not larger than a word are returned