This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] ia64-tdep.c: Fix alignment of struct args...


The patch below eliminates a FIXME regarding struct alignment in
inferior function calls on the IA-64.  To the best of my knowledge,
the calling conventions utilized by ia64-tdep.c now comply with the
IA-64 Software Conventions and Runtime Architecture Guide.

I've tested this code with the current gcc development sources
and the testsuite results related to this area look good.  (Other
results, however, are not so good, but this patch isn't responsible
for the poor results elsewhere.)  The gcc-2.96 compiler shipped with
recent IA-64 Red Hat Linux distributions still has bugs with regards
to struct alignment.

	* ia64-tdep.c (is_float_or_hfa_type_recurse): Call check_typedef()
	on types that we wish to recurse on.
	(slot_alignment_is_next_even): New function.
	(ia64_push_arguments): Call slot_alignment_is_next_even() to
	examine the type in order to decide if it's necessary to skip
	an odd slot.

Index: ia64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
retrieving revision 1.19
diff -u -p -r1.19 ia64-tdep.c
--- ia64-tdep.c	2001/06/01 02:39:51	1.19
+++ ia64-tdep.c	2001/06/02 01:35:12
@@ -1534,14 +1534,17 @@ is_float_or_hfa_type_recurse (struct typ
 	}
       break;
     case TYPE_CODE_ARRAY:
-      return is_float_or_hfa_type_recurse (TYPE_TARGET_TYPE (t), etp);
+      return
+	is_float_or_hfa_type_recurse (check_typedef (TYPE_TARGET_TYPE (t)),
+				      etp);
       break;
     case TYPE_CODE_STRUCT:
       {
 	int i;
 
 	for (i = 0; i < TYPE_NFIELDS (t); i++)
-	  if (!is_float_or_hfa_type_recurse (TYPE_FIELD_TYPE (t, i), etp))
+	  if (!is_float_or_hfa_type_recurse
+	      (check_typedef (TYPE_FIELD_TYPE (t, i)), etp))
 	    return 0;
 	return 1;
       }
@@ -1565,6 +1568,40 @@ is_float_or_hfa_type (struct type *t)
 }
 
 
+/* Return 1 if the alignment of T is such that the next even slot
+   should be used.  Return 0, if the next available slot should
+   be used.  (See section 8.5.1 of the IA-64 Software Conventions
+   and Runtime manual.)  */
+
+static int
+slot_alignment_is_next_even (struct type *t)
+{
+  switch (TYPE_CODE (t))
+    {
+    case TYPE_CODE_INT:
+    case TYPE_CODE_FLT:
+      if (TYPE_LENGTH (t) > 8)
+	return 1;
+      else
+	return 0;
+    case TYPE_CODE_ARRAY:
+      return
+	slot_alignment_is_next_even (check_typedef (TYPE_TARGET_TYPE (t)));
+    case TYPE_CODE_STRUCT:
+      {
+	int i;
+
+	for (i = 0; i < TYPE_NFIELDS (t); i++)
+	  if (slot_alignment_is_next_even
+	      (check_typedef (TYPE_FIELD_TYPE (t, i))))
+	    return 1;
+	return 0;
+      }
+    default:
+      return 0;
+    }
+}
+
 /* Attempt to find (and return) the global pointer for the given
    function.
 
@@ -1732,9 +1769,7 @@ ia64_push_arguments (int nargs, value_pt
       type = check_typedef (VALUE_TYPE (arg));
       len = TYPE_LENGTH (type);
 
-      /* FIXME: This is crude and it is wrong (IMO), but it matches
-         what gcc does, I think. */
-      if (len > 8 && (nslots & 1))
+      if ((nslots & 1) && slot_alignment_is_next_even (type))
 	nslots++;
 
       if (TYPE_CODE (type) == TYPE_CODE_FUNC)
@@ -1809,8 +1844,11 @@ ia64_push_arguments (int nargs, value_pt
 	}
 
       /* Normal slots */
-      if (len > 8 && (slotnum & 1))
+
+      /* Skip odd slot if necessary...  */
+      if ((slotnum & 1) && slot_alignment_is_next_even (type))
 	slotnum++;
+
       argoffset = 0;
       while (len > 0)
 	{


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]