This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 1/4] Aarch64: Func to detect args passed in float regs
- From: Alan Hayward <alan dot hayward at arm dot com>
- To: gdb-patches at sourceware dot org
- Cc: nd at arm dot com, Alan Hayward <alan dot hayward at arm dot com>
- Date: Mon, 20 Aug 2018 10:29:30 +0100
- Subject: [PATCH 1/4] Aarch64: Func to detect args passed in float regs
- References: <20180820092933.83224-1-alan.hayward@arm.com>
aapcs_is_vfp_call_or_return_candidate is as an eventual replacement
for is_hfa_or_hva.
This function is based on the GCC code
gcc/config/aarch64/aarch64.c:aarch64_vfp_is_call_or_return_candidate ()
2018-08-20 Alan Hayward <alan.hayward@arm.com>
* aarch64-tdep.c (HA_MAX_NUM_FLDS): New macro.
(aapcs_is_vfp_call_or_return_candidate_1): New function.
(aapcs_is_vfp_call_or_return_candidate): Likewise.
---
gdb/aarch64-tdep.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 141 insertions(+)
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 5c6eb98545..d3ea13f6f6 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -71,6 +71,10 @@
#define AARCH64_B0_REGNUM (AARCH64_H0_REGNUM + 32)
#define AARCH64_SVE_V0_REGNUM (AARCH64_B0_REGNUM + 32)
+/* A Homogeneous Floating-Point or Short-Vector Aggregate may have at most
+ four members. */
+#define HA_MAX_NUM_FLDS 4
+
/* All possible aarch64 target descriptors. */
struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1];
@@ -1209,6 +1213,143 @@ is_hfa_or_hva (struct type *ty)
return 0;
}
+/* Worker function for aapcs_is_vfp_call_or_return_candidate.
+
+ Return the number of register required, or -1 on failure.
+
+ When encountering a base element, if FUNDAMENTAL_TYPE is not set then set it
+ to the element, else fail if the type of this element does not match the
+ existing value. */
+
+static int
+aapcs_is_vfp_call_or_return_candidate_1 (struct type *type,
+ struct type **fundamental_type)
+{
+ if (type == nullptr)
+ return -1;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_FLT:
+ if (TYPE_LENGTH (type) > 16)
+ return -1;
+
+ if (*fundamental_type == nullptr)
+ *fundamental_type = type;
+ else if (TYPE_LENGTH (type) != TYPE_LENGTH (*fundamental_type)
+ || TYPE_CODE (type) != TYPE_CODE (*fundamental_type))
+ return -1;
+
+ return 1;
+
+ case TYPE_CODE_COMPLEX:
+ {
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_LENGTH (target_type) > 16)
+ return -1;
+
+ if (*fundamental_type == nullptr)
+ *fundamental_type = target_type;
+ else if (TYPE_LENGTH (target_type) != TYPE_LENGTH (*fundamental_type)
+ || TYPE_CODE (target_type) != TYPE_CODE (*fundamental_type))
+ return -1;
+
+ return 2;
+ }
+
+ case TYPE_CODE_ARRAY:
+ {
+ if (TYPE_VECTOR (type))
+ {
+ if (TYPE_LENGTH (type) != 8 && TYPE_LENGTH (type) != 16)
+ return -1;
+
+ if (*fundamental_type == nullptr)
+ *fundamental_type = type;
+ else if (TYPE_LENGTH (type) != TYPE_LENGTH (*fundamental_type)
+ || TYPE_CODE (type) != TYPE_CODE (*fundamental_type))
+ return -1;
+
+ return 1;
+ }
+ else
+ {
+ struct type *target_type = TYPE_TARGET_TYPE (type);
+ int count = aapcs_is_vfp_call_or_return_candidate_1
+ (target_type, fundamental_type);
+
+ if (count == -1)
+ return count;
+
+ count *= TYPE_LENGTH (type);
+ return count;
+ }
+ }
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ {
+ int count = 0;
+
+ for (int i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ struct type *member = check_typedef (TYPE_FIELD_TYPE (type, i));
+
+ int sub_count = aapcs_is_vfp_call_or_return_candidate_1
+ (member, fundamental_type);
+ if (sub_count == -1)
+ return -1;
+ count += sub_count;
+ }
+ return count;
+ }
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+/* Return true if an argument, whose type is described by TYPE, can be passed or
+ returned in simd/fp registers, providing enough parameter passing registers
+ are available. This is as described in the AAPCS64.
+
+ Upon successful return, *COUNT returns the number of needed registers,
+ *FUNDAMENTAL_TYPE contains the type of those registers.
+
+ Candidate as per the AAPCS64 5.4.2.C is either a:
+ - float.
+ - short-vector.
+ - HFA (Homogeneous Floating-point Aggregate, 4.3.5.1). A Composite type where
+ all the members are floats and has at most 4 members.
+ - HVA (Homogeneous Short-vector Aggregate, 4.3.5.2). A Composite type where
+ all the members are short vectors and has at most 4 members.
+ - Complex (7.1.1)
+
+ Note that HFAs and HVAs can include nested structures and arrays. */
+
+bool
+aapcs_is_vfp_call_or_return_candidate (struct type *type, int *count,
+ struct type **fundamental_type)
+{
+ if (type == nullptr)
+ return false;
+
+ *fundamental_type = nullptr;
+
+ int ag_count = aapcs_is_vfp_call_or_return_candidate_1 (type,
+ fundamental_type);
+
+ if (ag_count > 0 && ag_count <= HA_MAX_NUM_FLDS)
+ {
+ *count = ag_count;
+ return true;
+ }
+ else
+ return false;
+}
+
/* AArch64 function call information structure. */
struct aarch64_call_info
{
--
2.15.2 (Apple Git-101.1)