* arc-tdep.c (arc_bfd_mach_type): New static global.
authorDavid Edelsohn <dje.gcc@gmail.com>
Fri, 2 Jun 1995 18:29:46 +0000 (18:29 +0000)
committerDavid Edelsohn <dje.gcc@gmail.com>
Fri, 2 Jun 1995 18:29:46 +0000 (18:29 +0000)
(codestream_fill): Handle byte order differences.
(setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N".
(arc_get_frame_setup): Read it here.
(arc_frame_saved_pc): And here.
(arc_print_insn): New function.
(arc_set_cpu_type): Set arc_bfd_mach_type.  Don't set tm_print_insn.
(_initialize_arc_tdep): Set tm_print_insn to arc_print_insn.

gdb/ChangeLog
gdb/arc-tdep.c

index 9a1fe24..e0390fb 100644 (file)
@@ -1,3 +1,16 @@
+start-sanitize-arc
+Fri Jun  2 11:17:23 1995  Doug Evans  <dje@canuck.cygnus.com>
+
+       * arc-tdep.c (arc_bfd_mach_type): New static global.
+       (codestream_fill): Handle byte order differences.
+       (setup_prologue_scan): Don't read stdarg function's "sub sp,sp,N".
+       (arc_get_frame_setup): Read it here.
+       (arc_frame_saved_pc): And here.
+       (arc_print_insn): New function.
+       (arc_set_cpu_type): Set arc_bfd_mach_type.  Don't set tm_print_insn.
+       (_initialize_arc_tdep): Set tm_print_insn to arc_print_insn.
+end-sanitize-arc
+
 Wed May 31 12:04:01 1995  J.T. Conklin  <jtc@rtl.cygnus.com>
 
        * nlm/{configure.in, Makefile.in}: Converted to use autoconf.
index e76aa93..c684f0b 100644 (file)
@@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcmd.h"
 
 /* Current CPU, set with the "set cpu" command.  */
+static int arc_bfd_mach_type;
 char *arc_cpu_type;
 char *tmp_arc_cpu_type;
 
@@ -53,7 +54,8 @@ int debug_pipeline_p;
 
 #define OPMASK 0xf8000000
 
-/* Instruction field accessor macros.  */
+/* Instruction field accessor macros.
+   See the Programmer's Reference Manual.  */
 #define X_OP(i) (((i) >> 27) & 0x1f)
 #define X_A(i) (((i) >> 21) & 0x3f)
 #define X_B(i) (((i) >> 15) & 0x3f)
@@ -108,14 +110,25 @@ codestream_fill (peek_flag)
   codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
   codestream_off = 0;
   codestream_cnt = CODESTREAM_BUFSIZ;
-  /* FIXME: need to handle byte order differences.  */
   read_memory (codestream_addr, (char *) codestream_buf,
               CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
+  /* FIXME: check return code?  */
+
+  /* Handle byte order differences.  */
+  if (HOST_BYTE_ORDER != TARGET_BYTE_ORDER)
+    {
+      register unsigned int i, j, n = sizeof (codestream_buf[0]);
+      register char tmp, *p;
+      for (i = 0, p = (char *) codestream_buf; i < CODESTREAM_BUFSIZ;
+          ++i, p += n)
+       for (j = 0; j < n / 2; ++j)
+         tmp = p[j], p[j] = p[n - 1 - j], p[n - 1 - j] = tmp;
+    }
   
   if (peek_flag)
-    return (codestream_peek());
+    return codestream_peek ();
   else
-    return (codestream_get());
+    return codestream_get ();
 }
 
 static void
@@ -126,10 +139,12 @@ codestream_seek (place)
   codestream_next_addr *= CODESTREAM_BUFSIZ;
   codestream_cnt = 0;
   codestream_fill (1);
-  while (codestream_tell() != place)
+  while (codestream_tell () != place)
     codestream_get ();
 }
 
+/* This function is currently unused but leave in for now.  */
+
 static void
 codestream_read (buf, count)
      unsigned int *buf;
@@ -142,8 +157,7 @@ codestream_read (buf, count)
     *p++ = codestream_get ();
 }
 \f
-/* Set up prologue scanning and return the first insn,
-   not including the "sub sp,sp,32" of a stdarg function.  */
+/* Set up prologue scanning and return the first insn.  */
 
 static unsigned int
 setup_prologue_scan (pc)
@@ -154,12 +168,6 @@ setup_prologue_scan (pc)
   codestream_seek (pc);
   insn = codestream_get ();
 
-  /* The authority for what appears here is the home-grown ABI.  */
-
-  /* First insn may be "sub sp,sp,32" if stdarg fn.  */
-  if (insn == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 32))
-    insn = codestream_get ();
-
   return insn;
 }
 
@@ -176,17 +184,30 @@ arc_get_frame_setup (pc)
 {
   unsigned int insn;
   /* Size of frame or -1 if unrecognizable prologue.  */
-  int n = -1;
+  int frame_size = -1;
+  /* An initial "sub sp,sp,N" may or may not be for a stdarg fn.  */
+  int maybe_stdarg_decr = -1;
 
   insn = setup_prologue_scan (pc);
 
+  /* The authority for what appears here is the home-grown ABI.
+     The most recent version is 1.2.  */
+
+  /* First insn may be "sub sp,sp,N" if stdarg fn.  */
+  if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+      == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
+    {
+      maybe_stdarg_decr = X_D (insn);
+      insn = codestream_get ();
+    }
+
   if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))  /* st blink,[sp,4] */
       == BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
     {
       insn = codestream_get ();
       /* Frame may not be necessary, even though blink is saved.
         At least this is something we recognize.  */
-      n = 0;
+      frame_size = 0;
     }
 
   if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))          /* st fp,[sp] */
@@ -197,18 +218,18 @@ arc_get_frame_setup (pc)
               != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
        return -1;
 
-      /* Check for stack adjustment sub sp,sp,nnn.  */
+      /* Check for stack adjustment sub sp,sp,N.  */
       insn = codestream_peek ();
       if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
          == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
        {
          if (LIMM_P (X_C (insn)))
-           n = codestream_get ();
+           frame_size = codestream_get ();
          else if (SHIMM_P (X_C (insn)))
-           n = X_D (insn);
+           frame_size = X_D (insn);
          else
            return -1;
-         if (n < 0)
+         if (frame_size < 0)
            return -1;
 
           codestream_get ();
@@ -222,11 +243,20 @@ arc_get_frame_setup (pc)
       /* Frameless fn.  */
       else
        {
-         n = 0;
+         frame_size = 0;
        }
     }
 
-  return n;
+  /* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
+     stdarg fn.  The stdarg decrement is not treated as part of the frame size,
+     so we have a dilemma: what do we return?  For now, if we get a
+     "sub sp,sp,N" and nothing else assume this isn't a stdarg fn.  One way
+     to fix this completely would be to add a bit to the function descriptor
+     that says the function is a stdarg function.  */
+
+  if (frame_size < 0 && maybe_stdarg_decr > 0)
+    return maybe_stdarg_decr;
+  return frame_size;
 }
 
 /* Given a pc value, skip it forward past the function prologue by
@@ -283,13 +313,21 @@ arc_frame_saved_pc (frame)
       return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
     }
 
-  /* If the first insn is "st blink,[sp,4]" we can get blink from there.
+  /* The authority for what appears here is the home-grown ABI.
+     The most recent version is 1.2.  */
+
+  insn = setup_prologue_scan (func_start);
+
+  /* First insn may be "sub sp,sp,N" if stdarg fn.  */
+  if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
+      == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
+    insn = codestream_get ();
+
+  /* If the next insn is "st blink,[sp,4]" we can get blink from there.
      Otherwise this is a leaf function and we can use blink.  Note that
      this still allows for the case where a leaf function saves/clobbers/
      restores blink.  */
 
-  insn = setup_prologue_scan (func_start);
-
   if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))  /* st blink,[sp,4] */
       != BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
     return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
@@ -574,6 +612,30 @@ get_longjmp_target(pc)
 }
 #endif /* GET_LONGJMP_TARGET */
 \f
+/* Disassemble one instruction.  */
+
+static int
+arc_print_insn (vma, info)
+     bfd_vma vma;
+     disassemble_info *info;
+{
+  static int current_mach;
+  static int current_endian;
+  static disassembler_ftype current_disasm;
+
+  if (current_disasm == NULL
+      || arc_bfd_mach_type != current_mach
+      || TARGET_BYTE_ORDER != current_endian)
+    {
+      current_mach = arc_bfd_mach_type;
+      current_endian = TARGET_BYTE_ORDER;
+      current_disasm = arc_get_disassembler (current_mach,
+                                            current_endian == BIG_ENDIAN);
+    }
+
+  return (*current_disasm) (vma, info);
+}
+\f
 /* Command to set cpu type.  */
 
 void
@@ -627,8 +689,7 @@ arc_set_cpu_type (str)
       if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
        {
          arc_cpu_type = str;
-         tm_print_insn = arc_get_disassembler (arc_cpu_type_table[i].value,
-                                               TARGET_BYTE_ORDER == BIG_ENDIAN);
+         arc_bfd_mach_type = arc_cpu_type_table[i].value;
          return 1;
        }
     }
@@ -680,6 +741,5 @@ A negative value disables the timer.",
                   &setlist);
   c = add_show_from_set (c, &showlist);
 
-  /* FIXME: must be done after for now.  */
-  tm_print_insn = arc_get_disassembler (bfd_mach_arc_base, 1 /*FIXME*/);
+  tm_print_insn = arc_print_insn;
 }