* h8300-dis.c: Fix formatting.
[binutils-gdb.git] / gdb / ia64-tdep.c
index b81f6a032e736efbcb308b62d95a6efe063a4a6c..e220e27b5035660429fcb9050f34540a62a975a9 100644 (file)
@@ -23,6 +23,7 @@
 #include "inferior.h"
 #include "symfile.h"           /* for entry_point_address */
 #include "gdbcore.h"
+#include "arch-utils.h"
 #include "floatformat.h"
 
 #include "objfiles.h"
@@ -707,6 +708,11 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
   int mem_stack_frame_size = 0;
   int spill_reg   = 0;
   CORE_ADDR spill_addr = 0;
+  char instores[8];
+  char infpstores[8];
+
+  memset (instores, 0, sizeof instores);
+  memset (infpstores, 0, sizeof infpstores);
 
   if (frame && !frame->saved_regs)
     {
@@ -749,7 +755,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
       if (next_pc == 0)
        break;
 
-      if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
+      if (it == B || ((instr & 0x3fLL) != 0LL))
+       {
+         /* Exit loop upon hitting a branch instruction or a predicated
+            instruction. */
+         break;
+       }
+      else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
         {
          /* Move from BR */
          int b2 = (int) ((instr & 0x0000000e000LL) >> 13);
@@ -899,6 +911,48 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
                spill_addr = 0;         /* must be done spilling */
              last_prologue_pc = next_pc;
            }
+         else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
+           {
+             /* Allow up to one store of each input register. */
+             instores[rM-32] = 1;
+             last_prologue_pc = next_pc;
+           }
+       }
+      else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
+       {
+         /* One of
+              st1 [rN] = rM
+              st2 [rN] = rM
+              st4 [rN] = rM
+              st8 [rN] = rM
+            Note that the st8 case is handled in the clause above.
+            
+            Advance over stores of input registers. One store per input
+            register is permitted. */
+         int rM = (int) ((instr & 0x000000fe000LL) >> 13);
+         int qp = (int) (instr & 0x0000000003fLL);
+         if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
+           {
+             instores[rM-32] = 1;
+             last_prologue_pc = next_pc;
+           }
+       }
+      else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
+        {
+         /* Either
+              stfs [rN] = fM
+            or
+              stfd [rN] = fM
+
+            Advance over stores of floating point input registers.  Again
+            one store per register is permitted */
+         int fM = (int) ((instr & 0x000000fe000LL) >> 13);
+         int qp = (int) (instr & 0x0000000003fLL);
+         if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
+           {
+             infpstores[fM-8] = 1;
+             last_prologue_pc = next_pc;
+           }
        }
       else if (it == M
             && (   ((instr & 0x1ffc8000000LL) == 0x08ec0000000LL)
@@ -925,8 +979,6 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
              last_prologue_pc = next_pc;
            }
        }
-      else if (it == B || ((instr & 0x3fLL) != 0LL))
-       break;
 
       pc = next_pc;
     }
@@ -1845,7 +1897,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       os_ident = elf_elfheader (info.abfd)->e_ident[EI_OSABI];
 
       /* If os_ident is 0, it is not necessarily the case that we're on a
-         SYSV system.  (ELFOSABI_SYSV is defined to be 0.) GNU/Linux uses
+         SYSV system.  (ELFOSABI_NONE is defined to be 0.) GNU/Linux uses
         a note section to record OS/ABI info, but leaves e_ident[EI_OSABI]
         zero.  So we have to check for note sections too. */
       if (os_ident == 0)