diff options
Diffstat (limited to 'gdb/aarch64-tdep.c')
-rw-r--r-- | gdb/aarch64-tdep.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 8ce0eaa..2d1df03 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -921,11 +921,12 @@ aarch64_type_align (struct type *t) } } -/* 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)) { @@ -936,7 +937,10 @@ is_hfa (struct type *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; } @@ -944,12 +948,15 @@ is_hfa (struct type *ty) 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; @@ -1304,7 +1311,7 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, 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); @@ -1640,7 +1647,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, 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)); @@ -1654,7 +1661,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, 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)); } @@ -1705,14 +1712,10 @@ aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type) 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; } @@ -1778,7 +1781,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, } } } - 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)); @@ -1792,7 +1795,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, 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)); } |