Fix -Wuh and -Wnhu options so that they work.
[deliverable/binutils-gdb.git] / gdb / m68k-tdep.c
index 967bfbc58af6aed7214a41b622afd13331748f67..769ffe80b50934cf71180ecf4afecf01f00403bb 100644 (file)
@@ -15,13 +15,135 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "frame.h"
 #include "symtab.h"
+#include "gdbcore.h"
+#include "value.h"
+#include "gdb_string.h"
+#include "inferior.h"
 
 \f
+/* The only reason this is here is the tm-altos.h reference below.  It
+   was moved back here from tm-m68k.h.  FIXME? */
+
+extern CORE_ADDR
+altos_skip_prologue (pc)
+     CORE_ADDR pc;
+{
+  register int op = read_memory_integer (pc, 2);
+  if (op == 0047126)
+    pc += 4;   /* Skip link #word */
+  else if (op == 0044016)
+    pc += 6;   /* Skip link #long */
+  /* Not sure why branches are here.  */
+  /* From tm-isi.h, tm-altos.h */
+  else if (op == 0060000)
+    pc += 4;   /* Skip bra #word */
+  else if (op == 00600377)
+    pc += 6;   /* skip bra #long */
+  else if ((op & 0177400) == 0060000)
+    pc += 2;   /* skip bra #char */
+  return pc;
+}
+
+/* The only reason this is here is the tm-isi.h reference below.  It
+   was moved back here from tm-m68k.h.  FIXME? */
+
+extern CORE_ADDR
+isi_skip_prologue (pc)
+     CORE_ADDR pc;
+{
+  register int op = read_memory_integer (pc, 2);
+  if (op == 0047126)
+    pc += 4;   /* Skip link #word */
+  else if (op == 0044016)
+    pc += 6;   /* Skip link #long */
+  /* Not sure why branches are here.  */
+  /* From tm-isi.h, tm-altos.h */
+  else if (op == 0060000)
+    pc += 4;   /* Skip bra #word */
+  else if (op == 00600377)
+    pc += 6;   /* skip bra #long */
+  else if ((op & 0177400) == 0060000)
+    pc += 2;   /* skip bra #char */
+  return pc;
+}
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+int
+isi_frame_num_args (fi)
+     struct frame_info *fi;
+{
+  int val;
+  CORE_ADDR pc = FRAME_SAVED_PC (fi);
+  int insn = 0177777 & read_memory_integer (pc, 2);
+  val = 0;
+  if (insn == 0047757 || insn == 0157374)  /* lea W(sp),sp or addaw #W,sp */
+    val = read_memory_integer (pc + 2, 2);
+  else if ((insn & 0170777) == 0050217 /* addql #N, sp */
+          || (insn & 0170777) == 0050117)  /* addqw */
+    {
+      val = (insn >> 9) & 7;
+      if (val == 0)
+       val = 8;
+    }
+  else if (insn == 0157774) /* addal #WW, sp */
+    val = read_memory_integer (pc + 2, 4);
+  val >>= 2;
+  return val;
+}
+
+int
+delta68_frame_num_args (fi)
+     struct frame_info *fi;
+{
+  int val;
+  CORE_ADDR pc = FRAME_SAVED_PC (fi);
+  int insn = 0177777 & read_memory_integer (pc, 2);
+  val = 0;
+  if (insn == 0047757 || insn == 0157374)  /* lea W(sp),sp or addaw #W,sp */
+    val = read_memory_integer (pc + 2, 2);
+  else if ((insn & 0170777) == 0050217 /* addql #N, sp */
+          || (insn & 0170777) == 0050117)  /* addqw */
+    {
+      val = (insn >> 9) & 7;
+      if (val == 0)
+       val = 8;
+    }
+  else if (insn == 0157774) /* addal #WW, sp */
+    val = read_memory_integer (pc + 2, 4);
+  val >>= 2;
+  return val;
+}
+
+int
+news_frame_num_args (fi)
+     struct frame_info *fi;
+{
+  int val;
+  CORE_ADDR pc = FRAME_SAVED_PC (fi);
+  int insn = 0177777 & read_memory_integer (pc, 2);
+  val = 0;
+  if (insn == 0047757 || insn == 0157374)  /* lea W(sp),sp or addaw #W,sp */
+    val = read_memory_integer (pc + 2, 2);
+  else if ((insn & 0170777) == 0050217 /* addql #N, sp */
+          || (insn & 0170777) == 0050117)  /* addqw */
+    {
+      val = (insn >> 9) & 7;
+      if (val == 0)
+       val = 8;
+    }
+  else if (insn == 0157774) /* addal #WW, sp */
+    val = read_memory_integer (pc + 2, 4);
+  val >>= 2;
+  return val;
+}
+
 /* Push an empty stack frame, to record the current PC, etc.  */
 
 void
@@ -34,13 +156,15 @@ m68k_push_dummy_frame ()
   sp = push_word (sp, read_register (PC_REGNUM));
   sp = push_word (sp, read_register (FP_REGNUM));
   write_register (FP_REGNUM, sp);
-#if defined (HAVE_68881)
+
+  /* Always save the floating-point registers, whether they exist on
+     this target or not.  */
   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
     {
       read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
       sp = push_bytes (sp, raw_buffer, 12);
     }
-#endif
+
   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
     {
       sp = push_word (sp, read_register (regnum));
@@ -55,17 +179,14 @@ m68k_push_dummy_frame ()
 void
 m68k_pop_frame ()
 {
-  register FRAME frame = get_current_frame ();
+  register struct frame_info *frame = get_current_frame ();
   register CORE_ADDR fp;
   register int regnum;
   struct frame_saved_regs fsr;
-  struct frame_info *fi;
   char raw_buffer[12];
 
-  fi = get_frame_info (frame);
-  fp = fi -> frame;
-  get_frame_saved_regs (fi, &fsr);
-#if defined (HAVE_68881)
+  fp = FRAME_FP (frame);
+  get_frame_saved_regs (frame, &fsr);
   for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--)
     {
       if (fsr.regs[regnum])
@@ -74,7 +195,6 @@ m68k_pop_frame ()
          write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
        }
     }
-#endif
   for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--)
     {
       if (fsr.regs[regnum])
@@ -90,8 +210,6 @@ m68k_pop_frame ()
   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
   write_register (SP_REGNUM, fp + 8);
   flush_cached_frames ();
-  set_current_frame (create_new_frame (read_register (FP_REGNUM),
-                                      read_pc ()));
 }
 
 \f
@@ -160,6 +278,10 @@ CORE_ADDR ip;
        {
          ip += 4;      /* Skip link.w */
        }
+      else if (op == 0x4856)
+       ip += 2; /* Skip pea %fp */
+      else if (op == 0x2c4f)
+       ip += 2; /* Skip move.l %sp, %fp */
       else if (op == P_LINK_L)
        {
          ip += 6;      /* Skip link.l */
@@ -192,11 +314,7 @@ m68k_find_saved_regs (frame_info, saved_regs)
 
   /* First possible address for a pc in a call dummy for this frame.  */
   CORE_ADDR possible_call_dummy_start =
-    (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4
-#if defined (HAVE_68881)
-      - 8*12
-#endif
-       ;
+    (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12;
 
   int nextinsn;
   memset (saved_regs, 0, sizeof (*saved_regs));
@@ -207,9 +325,7 @@ m68k_find_saved_regs (frame_info, saved_regs)
       /* It is a call dummy.  We could just stop now, since we know
         what the call dummy saves and where.  But this code proceeds
         to parse the "prologue" which is part of the call dummy.
-        This is needlessly complex, confusing, and also is the only
-        reason that the call dummy is customized based on HAVE_68881.
-        FIXME.  */
+        This is needlessly complex and confusing.  FIXME.  */
 
       next_addr = (frame_info)->frame;
       pc = possible_call_dummy_start;
@@ -217,20 +333,35 @@ m68k_find_saved_regs (frame_info, saved_regs)
   else                                                                 
     {
       pc = get_pc_function_start ((frame_info)->pc);                   
-      /* Verify we have a link a6 instruction next;                    
-        if not we lose.  If we win, find the address above the saved   
-        regs using the amount of storage from the link instruction.  */
-      if (044016 == read_memory_integer (pc, 2))                       
+
+      if (0x4856 == read_memory_integer (pc, 2)
+         && 0x2c4f == read_memory_integer (pc + 2, 2))
+       {
+         /*
+           pea %fp
+            move.l %sp, %fp */
+
+         pc += 4;
+         next_addr = frame_info->frame;
+       }
+      else if (044016 == read_memory_integer (pc, 2))
+       /* link.l %fp */
+       /* Find the address above the saved   
+          regs using the amount of storage from the link instruction.  */
        next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; 
       else if (047126 == read_memory_integer (pc, 2))                  
+       /* link.w %fp */
+       /* Find the address above the saved   
+          regs using the amount of storage from the link instruction.  */
        next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; 
-      else goto lose;                                                  
+      else goto lose;
+
       /* If have an addal #-n, sp next, adjust next_addr.  */          
       if ((0177777 & read_memory_integer (pc, 2)) == 0157774)          
        next_addr += read_memory_integer (pc += 2, 4), pc += 4;         
     }                                                                  
   regmask = read_memory_integer (pc + 2, 2);                           
-#if defined (HAVE_68881)
+
   /* Here can come an fmovem.  Check for it.  */               
   nextinsn = 0xffff & read_memory_integer (pc, 2);                     
   if (0xf227 == nextinsn                                               
@@ -240,7 +371,7 @@ m68k_find_saved_regs (frame_info, saved_regs)
        if (regmask & 1)                                                
           saved_regs->regs[regnum] = (next_addr -= 12);                
       regmask = read_memory_integer (pc + 2, 2); }
-#endif
+
   /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */     
   if (0044327 == read_memory_integer (pc, 2))                          
     { pc += 4; /* Regmask's low bit is for register 0, the first written */ 
@@ -267,7 +398,7 @@ m68k_find_saved_regs (frame_info, saved_regs)
          saved_regs->regs[regnum] = (next_addr -= 4);
        }
     }
-#if defined (HAVE_68881)
+
   /* fmovemx to index of sp may follow.  */                            
   regmask = read_memory_integer (pc + 2, 2);                           
   nextinsn = 0xffff & read_memory_integer (pc, 2);                     
@@ -278,7 +409,7 @@ m68k_find_saved_regs (frame_info, saved_regs)
        if (regmask & 1)                                                
           saved_regs->regs[regnum] = (next_addr += 12) - 12;   
       regmask = read_memory_integer (pc + 2, 2); }                     
-#endif
+
   /* clrw -(sp); movw ccr,-(sp) may follow.  */                                
   if (0x426742e7 == read_memory_integer (pc, 4))                       
     saved_regs->regs[PS_REGNUM] = (next_addr -= 4);            
@@ -328,6 +459,11 @@ m68k_find_saved_regs (frame_info, saved_regs)
 
  */
 
+/* Atari SVR4 has R_SR but not R_PS */
+
+#if !defined (R_PS) && defined (R_SR)
+#define R_PS R_SR
+#endif
 
 /*  Given a pointer to a general register set in /proc format (gregset_t *),
     unpack the register contents and supply them as gdb's idea of the current
@@ -355,7 +491,6 @@ int regno;
 {
   register int regi;
   register greg_t *regp = (greg_t *) gregsetp;
-  extern char registers[];
 
   for (regi = 0 ; regi < R_PC ; regi++)
     {
@@ -410,7 +545,6 @@ int regno;
   int regi;
   char *to;
   char *from;
-  extern char registers[];
 
   for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
     {
@@ -480,15 +614,20 @@ CORE_ADDR
 m68k_saved_pc_after_call(frame)
      struct frame_info *frame;
 {
-#ifdef GDB_TARGET_IS_SUN3
+#ifdef SYSCALL_TRAP
   int op;
 
-  op = read_memory_integer (frame->pc, 2);
-  op &= 0xFFFF;
+  op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
 
-  if (op == P_TRAP)
+  if (op == SYSCALL_TRAP)
     return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
   else
-#endif /* GDB_TARGET_IS_SUN3 */
+#endif /* SYSCALL_TRAP */
     return read_memory_integer (read_register (SP_REGNUM), 4);
 }
+
+void
+_initialize_m68k_tdep ()
+{
+  tm_print_insn = print_insn_m68k;
+}
This page took 0.026559 seconds and 4 git commands to generate.