}
}
-/* Return 1 if *TY is a homogeneous floating-point aggregate as
- defined in the AAPCS64 ABI document; otherwise return 0. */
+/* Return 1 if *TY is a homogeneous floating-point aggregate or
+ homogeneous short-vector aggregate as defined in the AAPCS64 ABI
+ document; otherwise return 0. */
static int
-is_hfa (struct type *ty)
+is_hfa_or_hva (struct type *ty)
{
switch (TYPE_CODE (ty))
{
if (TYPE_VECTOR (ty))
return 0;
- if (TYPE_CODE (target_ty) == TYPE_CODE_FLT && TYPE_LENGTH (ty) <= 4)
+ if (TYPE_LENGTH (ty) <= 4 /* HFA or HVA has at most 4 members. */
+ && (TYPE_CODE (target_ty) == TYPE_CODE_FLT /* HFA */
+ || (TYPE_CODE (target_ty) == TYPE_CODE_ARRAY /* HVA */
+ && TYPE_VECTOR (target_ty))))
return 1;
break;
}
case TYPE_CODE_UNION:
case TYPE_CODE_STRUCT:
{
+ /* HFA or HVA has at most four members. */
if (TYPE_NFIELDS (ty) > 0 && TYPE_NFIELDS (ty) <= 4)
{
struct type *member0_type;
member0_type = check_typedef (TYPE_FIELD_TYPE (ty, 0));
- if (TYPE_CODE (member0_type) == TYPE_CODE_FLT)
+ if (TYPE_CODE (member0_type) == TYPE_CODE_FLT
+ || (TYPE_CODE (member0_type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (member0_type)))
{
int i;
case TYPE_CODE_STRUCT:
case TYPE_CODE_ARRAY:
case TYPE_CODE_UNION:
- if (is_hfa (arg_type))
+ if (is_hfa_or_hva (arg_type))
{
int elements = TYPE_NFIELDS (arg_type);
memcpy (valbuf, buf, len);
valbuf += len;
}
- else if (is_hfa (type))
+ else if (is_hfa_or_hva (type))
{
int elements = TYPE_NFIELDS (type);
struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
if (aarch64_debug)
{
- debug_printf ("read HFA return value element %d from %s\n",
+ debug_printf ("read HFA or HVA return value element %d from %s\n",
i + 1,
gdbarch_register_name (gdbarch, regno));
}
type = check_typedef (type);
- /* In the AArch64 ABI, "integer" like aggregate types are returned
- in registers. For an aggregate type to be integer like, its size
- must be less than or equal to 4 * X_REGISTER_SIZE. */
-
- if (is_hfa (type))
+ if (is_hfa_or_hva (type))
{
- /* PCS B.5 If the argument is a Named HFA, then the argument is
- used unmodified. */
+ /* v0-v7 are used to return values and one register is allocated
+ for one member. However, HFA or HVA has at most four members. */
return 0;
}
}
}
}
- else if (is_hfa (type))
+ else if (is_hfa_or_hva (type))
{
int elements = TYPE_NFIELDS (type);
struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
if (aarch64_debug)
{
- debug_printf ("write HFA return value element %d to %s\n",
+ debug_printf ("write HFA or HVA return value element %d to %s\n",
i + 1,
gdbarch_register_name (gdbarch, regno));
}