* cgen-asm.c: Include symcat.h.
authorDoug Evans <dje@google.com>
Mon, 23 Feb 1998 21:17:29 +0000 (21:17 +0000)
committerDoug Evans <dje@google.com>
Mon, 23 Feb 1998 21:17:29 +0000 (21:17 +0000)
* cgen-dis.c,cgen-opc.c,cgen-asm.in,cgen-dis.in: Ditto.

opcodes/ChangeLog
opcodes/cgen-asm.in
opcodes/cgen-dis.in

index 0c9a518bb5da7ebdf5df3d2a13df13096ca3f86d..9b3b25edfd4c0873eb38bb9b048c3c36080007c8 100644 (file)
@@ -1,3 +1,8 @@
+Mon Feb 23 13:16:17 1998  Doug Evans  <devans@seba.cygnus.com>
+
+       * cgen-asm.c: Include symcat.h.
+       * cgen-dis.c,cgen-opc.c,cgen-asm.in,cgen-dis.in: Ditto.
+
 start-sanitize-sky
 Mon Feb 23 09:51:39 1998  Doug Evans  <devans@canuck.cygnus.com>
 
index 8a5099b4ed7c965359536f2a08b44df85cf9a62e..37250da97d52b096ca389a9ea4a77bcb77be0952 100644 (file)
@@ -3,7 +3,7 @@
 
 This file is used to generate @arch@-asm.c.
 
-Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
 
 This file is part of the GNU Binutils and GDB, the GNU debugger.
 
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <stdio.h>
 #include "ansidecl.h"
 #include "bfd.h"
+#include "symcat.h"
 #include "@arch@-opc.h"
 
 /* ??? The layout of this stuff is still work in progress.
@@ -35,33 +36,66 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    compiled with GCC), or switch to macros, or use something else.
 */
 
-static const char *parse_insn_normal
+static const char * parse_insn_normal
      PARAMS ((const CGEN_INSN *, const char **, CGEN_FIELDS *));
-static void insert_insn_normal
+static const char * insert_insn_normal
      PARAMS ((const CGEN_INSN *, CGEN_FIELDS *, cgen_insn_t *));
 \f
 /* Default insertion routine.
 
-   SHIFT is negative for left shifts, positive for right shifts.
-   All bits of VALUE to be inserted must be valid as we don't handle
-   signed vs unsigned shifts.
+   ATTRS is a mask of the boolean attributes.
+   LENGTH is the length of VALUE in bits.
+   TOTAL_LENGTH is the total length of the insn (currently 8,16,32).
 
-   ATTRS is a mask of the boolean attributes.  We don't need any at the
-   moment, but for consistency with extract_normal we have them.  */
+   The result is an error message or NULL if success.  */
 
-/* FIXME: This duplicates functionality with bfd's howto table and
+/* ??? This duplicates functionality with bfd's howto table and
    bfd_install_relocation.  */
-/* FIXME: For architectures where insns can be representable as ints,
-   store insn in `field' struct and add registers, etc. while parsing.  */
+/* ??? For architectures where insns can be representable as ints,
+   store insn in `field' struct and add registers, etc. while parsing?  */
 
-static CGEN_INLINE void
+static const char *
 insert_normal (value, attrs, start, length, shift, total_length, buffer)
      long value;
      unsigned int attrs;
-     int start, length, shift, total_length;
-     char *buffer;
+     int start;
+     int length;
+     int shift;
+     int total_length;
+     char * buffer;
 {
   bfd_vma x;
+  static char buf[100];
+
+  if (shift < 0)
+    value <<= -shift;
+  else
+    value >>= shift;
+
+  /* Ensure VALUE will fit.  */
+  if ((attrs & (1 << CGEN_OPERAND_UNSIGNED)) != 0)
+    {
+      unsigned long max = (1 << length) - 1;
+      if ((unsigned long) value > max)
+       {
+         const char *err = "operand out of range (%lu not between 0 and %lu)";
+
+         sprintf (buf, err, value, max);
+         return buf;
+       }
+    }
+  else
+    {
+      long min = - (1 << (length - 1));
+      long max = (1 << (length - 1)) - 1;
+      if (value < min || value > max)
+       {
+         const char *err = "operand out of range (%ld not between %ld and %ld)";
+
+         sprintf (buf, err, value, min, max);
+         return buf;
+       }
+    }
 
 #if 0 /*def CGEN_INT_INSN*/
   *buffer |= ((value & ((1 << length) - 1))
@@ -70,7 +104,7 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
   switch (total_length)
     {
     case 8:
-      x = *(unsigned char *) buffer;
+      x = * (unsigned char *) buffer;
       break;
     case 16:
       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
@@ -88,18 +122,13 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
       abort ();
     }
 
-  if (shift < 0)
-    value <<= -shift;
-  else
-    value >>= shift;
-
   x |= ((value & ((1 << length) - 1))
        << (total_length - (start + length)));
 
   switch (total_length)
     {
     case 8:
-      *buffer = value;
+      * buffer = value;
       break;
     case 16:
       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
@@ -117,6 +146,8 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
       abort ();
     }
 #endif
+
+  return NULL;
 }
 \f
 /* -- assembler routines inserted here */
@@ -137,15 +168,15 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
 
 static const char *
 parse_insn_normal (insn, strp, fields)
-     const CGEN_INSN *insn;
-     const char **strp;
-     CGEN_FIELDS *fields;
+     const CGEN_INSN * insn;
+     const char ** strp;
+     CGEN_FIELDS * fields;
 {
-  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
-  const char *str = *strp;
-  const char *errmsg;
-  const char *p;
-  const unsigned char *syn;
+  const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
+  const char * str = *strp;
+  const char * errmsg;
+  const char * p;
+  const unsigned char * syn;
 #ifdef CGEN_MNEMONIC_OPERANDS
   int past_opcode_p;
 #endif
@@ -153,9 +184,9 @@ parse_insn_normal (insn, strp, fields)
   /* For now we assume the mnemonic is first (there are no leading operands).
      We can parse it without needing to set up operand parsing.  */
   p = CGEN_INSN_MNEMONIC (insn);
-  while (*p && *p == *str)
-    ++p, ++str;
-  if (*p || (*str && !isspace (*str)))
+  while (* p && * p == * str)
+    ++ p, ++ str;
+  if (* p || (* str && !isspace (* str)))
     return "unrecognized instruction";
 
   CGEN_INIT_PARSE ();
@@ -167,29 +198,33 @@ parse_insn_normal (insn, strp, fields)
   /* We don't check for (*str != '\0') here because we want to parse
      any trailing fake arguments in the syntax string.  */
   syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
+
   /* Mnemonics come first for now, ensure valid string.  */
-  if (! CGEN_SYNTAX_MNEMONIC_P (*syn))
+  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
     abort ();
+
   ++syn;
-  while (*syn != 0)
+
+  while (* syn != 0)
     {
       /* Non operand chars must match exactly.  */
       /* FIXME: Need to better handle whitespace.  */
-      if (CGEN_SYNTAX_CHAR_P (*syn))
+      if (CGEN_SYNTAX_CHAR_P (* syn))
        {
-         if (*str == CGEN_SYNTAX_CHAR (*syn))
+         if (*str == CGEN_SYNTAX_CHAR (* syn))
            {
 #ifdef CGEN_MNEMONIC_OPERANDS
-             if (*syn == ' ')
+             if (* syn == ' ')
                past_opcode_p = 1;
 #endif
-             ++syn;
-             ++str;
+             ++ syn;
+             ++ str;
            }
          else
            {
              /* Syntax char didn't match.  Can't be this insn.  */
-             /* FIXME: would like to return "expected char `c'" */
+             /* FIXME: would like to return something like
+                "expected char `c'" */
              return "syntax error";
            }
          continue;
@@ -202,20 +237,20 @@ parse_insn_normal (insn, strp, fields)
        return errmsg;
 
       /* Done with this operand, continue with next one.  */
-      ++syn;
+      ++ syn;
     }
 
   /* If we're at the end of the syntax string, we're done.  */
-  if (*syn == '\0')
+  if (* syn == '\0')
     {
       /* FIXME: For the moment we assume a valid `str' can only contain
         blanks now.  IE: We needn't try again with a longer version of
         the insn and it is assumed that longer versions of insns appear
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
-      while (isspace (*str))
-       ++str;
+      while (isspace (* str))
+       ++ str;
 
-      if (*str != '\0')
+      if (* str != '\0')
        return "junk at end of line"; /* FIXME: would like to include `str' */
 
       return NULL;
@@ -226,17 +261,19 @@ parse_insn_normal (insn, strp, fields)
 }
 
 /* Default insn builder (insert handler).
-   The instruction is recorded in target byte order.  */
+   The instruction is recorded in target byte order.
+   The result is an error message or NULL if success.  */
+/* FIXME: change buffer to char *?  */
 
-static void
+static const char *
 insert_insn_normal (insn, fields, buffer)
-     const CGEN_INSN *insn;
-     CGEN_FIELDS *fields;
-     cgen_insn_t *buffer;
+     const CGEN_INSN * insn;
+     CGEN_FIELDS * fields;
+     cgen_insn_t * buffer;
 {
-  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+  const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
   bfd_vma value;
-  const unsigned char *syn;
+  const unsigned char * syn;
 
   CGEN_INIT_INSERT ();
   value = CGEN_INSN_VALUE (insn);
@@ -251,7 +288,7 @@ insert_insn_normal (insn, fields, buffer)
   switch (min (CGEN_BASE_INSN_BITSIZE, CGEN_FIELDS_BITSIZE (fields)))
     {
     case 8:
-      *buffer = value;
+      * buffer = value;
       break;
     case 16:
       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
@@ -273,13 +310,20 @@ insert_insn_normal (insn, fields, buffer)
   /* ??? Rather than scanning the syntax string again, we could store
      in `fields' a null terminated list of the fields that are present.  */
 
-  for (syn = CGEN_SYNTAX_STRING (syntax); *syn != '\0'; ++syn)
+  for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
     {
-      if (CGEN_SYNTAX_CHAR_P (*syn))
+      const char *errmsg;
+
+      if (CGEN_SYNTAX_CHAR_P (* syn))
        continue;
 
-      @arch@_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields, buffer);
+      errmsg = @arch@_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields,
+                                          (char *) buffer);
+      if (errmsg)
+       return errmsg;
     }
+
+  return NULL;
 }
 \f
 /* Main entry point.
@@ -292,17 +336,17 @@ insert_insn_normal (insn, fields, buffer)
 
 const CGEN_INSN *
 @arch@_cgen_assemble_insn (str, fields, buf, errmsg)
-     const char *str;
-     CGEN_FIELDS *fields;
-     cgen_insn_t *buf;
-     char **errmsg;
+     const char * str;
+     CGEN_FIELDS * fields;
+     cgen_insn_t * buf;
+     char ** errmsg;
 {
-  const char *start;
-  CGEN_INSN_LIST *ilist;
+  const char * start;
+  CGEN_INSN_LIST * ilist;
 
   /* Skip leading white space.  */
-  while (isspace (*str))
-    ++str;
+  while (isspace (* str))
+    ++ str;
 
   /* The instructions are stored in hashed lists.
      Get the first in the list.  */
@@ -336,16 +380,10 @@ const CGEN_INSN *
       /* FIXME: wip */
       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
 
-      /* ??? The extent to which moving the parse and insert handlers into
-         this function (thus removing the function call) will speed things up
-        is unclear.  The simplicity and flexibility of the current scheme is
-        appropriate for now.  One could have the best of both worlds with
-        inline functions but of course that would only work for gcc.  Since
-        we're machine generating some code we could do that here too.  Maybe
-        later.  */
-      if (! (*CGEN_PARSE_FN (insn)) (insn, &str, fields))
+      if (! CGEN_PARSE_FN (insn) (insn, & str, fields))
        {
-         (*CGEN_INSERT_FN (insn)) (insn, fields, buf);
+         if (CGEN_INSERT_FN (insn) (insn, fields, buf) != NULL)
+           continue;
          /* It is up to the caller to actually output the insn and any
             queued relocs.  */
          return insn;
@@ -376,12 +414,12 @@ const CGEN_INSN *
 
 void
 @arch@_cgen_asm_hash_keywords (opvals)
-     CGEN_KEYWORD *opvals;
+     CGEN_KEYWORD * opvals;
 {
   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
-  const CGEN_KEYWORD_ENTRY *ke;
+  const CGEN_KEYWORD_ENTRY * ke;
 
-  while ((ke = cgen_keyword_search_next (&search)) != NULL)
+  while ((ke = cgen_keyword_search_next (& search)) != NULL)
     {
 #if 0 /* Unnecessary, should be done in the search routine.  */
       if (! @arch@_cgen_opval_supported (ke))
index 0724b4425780f1fe210ecea3c64eaff45eccf808..06e22eb72f69782594d2b48b416e6a06f78eb585 100644 (file)
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "ansidecl.h"
 #include "dis-asm.h"
 #include "bfd.h"
+#include "symcat.h"
 #include "@arch@-opc.h"
 
 /* ??? The layout of this stuff is still work in progress.
@@ -87,6 +88,8 @@ extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length,
     value <<= shift;
 
   *valuep = value;
+
+  /* FIXME: for now */
   return 1;
 }
 
@@ -166,7 +169,7 @@ extract_insn_normal (insn, buf_ctrl, insn_value, fields)
        continue;
 
       length = @arch@_cgen_extract_operand (CGEN_SYNTAX_FIELD (*syn),
-                                          buf_ctrl, insn_value, fields);
+                                           buf_ctrl, insn_value, fields);
       if (length == 0)
        return 0;
     }