* gdbint.texinfo (Host Definition): Remove description of
[deliverable/binutils-gdb.git] / gdb / ia64-tdep.c
index afa0e1c76b99f883977c03e6673d5b80873b5c59..9bbf31757262a05eaf849e770165c727fa746e4b 100644 (file)
@@ -26,6 +26,7 @@
 #include "arch-utils.h"
 #include "floatformat.h"
 #include "regcache.h"
+#include "doublest.h"
 
 #include "objfiles.h"
 #include "elf/common.h"                /* for DT_PLTGOT value */
@@ -859,10 +860,11 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
       if (next_pc == 0)
        break;
 
-      if (it == B || ((instr & 0x3fLL) != 0LL))
+      if ((it == B && ((instr & 0x1e1f800003f) != 0x04000000000))
+          || ((instr & 0x3fLL) != 0LL))
        {
-         /* Exit loop upon hitting a branch instruction or a predicated
-            instruction. */
+         /* Exit loop upon hitting a non-nop branch instruction 
+            or a predicated instruction. */
          break;
        }
       else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
@@ -1534,14 +1536,17 @@ is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
        }
       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 +1570,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.
 
@@ -1712,11 +1751,11 @@ find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr)
 }
 
 CORE_ADDR
-ia64_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
+ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                    int struct_return, CORE_ADDR struct_addr)
 {
   int argno;
-  value_ptr arg;
+  struct value *arg;
   struct type *type;
   int len, argoffset;
   int nslots, rseslots, memslots, slotnum, nfuncargs;
@@ -1732,9 +1771,7 @@ ia64_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
       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 +1846,11 @@ ia64_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
        }
 
       /* 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)
        {
This page took 0.025433 seconds and 4 git commands to generate.