Add new field to disassemble_info structure: symbol_is_valid() and use it to
[deliverable/binutils-gdb.git] / opcodes / fr30-asm.c
index da62c6e786a4b479e349f6a87f625b1b9d5003f0..f1c18a16bd5f10d4662fbdc24032fee7bac80f39 100644 (file)
@@ -26,7 +26,6 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
    Keep that in mind.  */
 
 #include "sysdep.h"
    Keep that in mind.  */
 
 #include "sysdep.h"
-#include <ctype.h>
 #include <stdio.h>
 #include "ansidecl.h"
 #include "bfd.h"
 #include <stdio.h>
 #include "ansidecl.h"
 #include "bfd.h"
@@ -36,16 +35,17 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
 #include "opintl.h"
 #include "xregex.h"
 #include "libiberty.h"
 #include "opintl.h"
 #include "xregex.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 
 
-#undef min
+#undef  min
 #define min(a,b) ((a) < (b) ? (a) : (b))
 #define min(a,b) ((a) < (b) ? (a) : (b))
-#undef max
+#undef  max
 #define max(a,b) ((a) > (b) ? (a) : (b))
 
 static const char * parse_insn_normal
 #define max(a,b) ((a) > (b) ? (a) : (b))
 
 static const char * parse_insn_normal
-     PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
+  (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
 \f
 \f
-/* -- assembler routines inserted here */
+/* -- assembler routines inserted here */
 
 /* -- asm.c */
 /* Handle register lists for LDMx and STMx.  */
 
 /* -- asm.c */
 /* Handle register lists for LDMx and STMx.  */
@@ -186,8 +186,7 @@ const char * fr30_cgen_parse_operand
 
    This function could be moved into `parse_insn_normal', but keeping it
    separate makes clear the interface between `parse_insn_normal' and each of
 
    This function could be moved into `parse_insn_normal', but keeping it
    separate makes clear the interface between `parse_insn_normal' and each of
-   the handlers.
-*/
+   the handlers.  */
 
 const char *
 fr30_cgen_parse_operand (cd, opindex, strp, fields)
 
 const char *
 fr30_cgen_parse_operand (cd, opindex, strp, fields)
@@ -345,25 +344,22 @@ fr30_cgen_init_asm (cd)
 
 \f
 
 
 \f
 
-/*
-  Regex construction routine.
+/* Regex construction routine.
 
 
-  This translates an opcode syntax string into a regex string,
-  by replacing any non-character syntax element (such as an
-  opcode) with the pattern '.*'
+   This translates an opcode syntax string into a regex string,
+   by replacing any non-character syntax element (such as an
+   opcode) with the pattern '.*'
 
 
-  It then compiles the regex and stores it in the opcode, for
-  later use by fr30_cgen_assemble_insn
+   It then compiles the regex and stores it in the opcode, for
+   later use by fr30_cgen_assemble_insn
 
 
-  Returns NULL for success, an error message for failure. */
+   Returns NULL for success, an error message for failure.  */
 
 char * 
 
 char * 
-fr30_cgen_build_insn_regex (insn)
-     CGEN_INSN *insn;
+fr30_cgen_build_insn_regex (CGEN_INSN *insn)
 {  
   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
   const char *mnem = CGEN_INSN_MNEMONIC (insn);
 {  
   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
   const char *mnem = CGEN_INSN_MNEMONIC (insn);
-  int mnem_len;
   char rxbuf[CGEN_MAX_RX_ELEMENTS];
   char *rx = rxbuf;
   const CGEN_SYNTAX_CHAR_TYPE *syn;
   char rxbuf[CGEN_MAX_RX_ELEMENTS];
   char *rx = rxbuf;
   const CGEN_SYNTAX_CHAR_TYPE *syn;
@@ -371,72 +367,100 @@ fr30_cgen_build_insn_regex (insn)
 
   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
 
 
   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
 
-  /* Mnemonics come first in the syntax string  */
-  if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) return "missing mnemonic in syntax string";
+  /* Mnemonics come first in the syntax string.  */
+  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
+    return _("missing mnemonic in syntax string");
   ++syn;
 
   ++syn;
 
-  /* copy the literal mnemonic out of the insn */
-  memset (rx, 0, CGEN_MAX_RX_ELEMENTS);
-  mnem_len = strlen(mnem);
-  memcpy (rx, mnem, mnem_len);
-  rx += mnem_len;
+  /* Generate a case sensitive regular expression that emulates case
+     insensitive matching in the "C" locale.  We cannot generate a case
+     insensitive regular expression because in Turkish locales, 'i' and 'I'
+     are not equal modulo case conversion.  */
 
 
-  /* copy any remaining literals from the syntax string into the rx */
-  for(; * syn != 0 && rx < rxbuf + (CGEN_MAX_RX_ELEMENTS - 9); ++syn, ++rx) 
+  /* Copy the literal mnemonic out of the insn.  */
+  for (; *mnem; mnem++)
+    {
+      char c = *mnem;
+
+      if (ISALPHA (c))
+       {
+         *rx++ = '[';
+         *rx++ = TOLOWER (c);
+         *rx++ = TOUPPER (c);
+         *rx++ = ']';
+       }
+      else
+       *rx++ = c;
+    }
+
+  /* Copy any remaining literals from the syntax string into the rx.  */
+  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
     {
       if (CGEN_SYNTAX_CHAR_P (* syn)) 
        {
     {
       if (CGEN_SYNTAX_CHAR_P (* syn)) 
        {
-        char tmp = CGEN_SYNTAX_CHAR (* syn);
-        switch (tmp) 
-           {
-            /* escape any regex metacharacters in the syntax */
-          case '.': case '[': case '\\': 
-          case '*': case '^': case '$': 
+         char c = CGEN_SYNTAX_CHAR (* syn);
+
+         switch (c) 
+           {
+             /* Escape any regex metacharacters in the syntax.  */
+           case '.': case '[': case '\\': 
+           case '*': case '^': case '$': 
 
 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
 
 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
-          case '?': case '{': case '}': 
-          case '(': case ')': case '*':
-          case '|': case '+': case ']':
+           case '?': case '{': case '}': 
+           case '(': case ')': case '*':
+           case '|': case '+': case ']':
 #endif
 #endif
-
-            * rx++ = '\\';
-            break;  
-          }
-        /* insert syntax char into rx */
-       * rx = tmp;
+             *rx++ = '\\';
+             *rx++ = c;
+             break;
+
+           default:
+             if (ISALPHA (c))
+               {
+                 *rx++ = '[';
+                 *rx++ = TOLOWER (c);
+                 *rx++ = TOUPPER (c);
+                 *rx++ = ']';
+               }
+             else
+               *rx++ = c;
+             break;
+           }
        }
       else
        {
        }
       else
        {
-         /* replace non-syntax fields with globs */
-         * rx = '.';
-         * ++rx = '*';
+         /* Replace non-syntax fields with globs.  */
+         *rx++ = '.';
+         *rx++ = '*';
        }
     }
 
        }
     }
 
-  /* trailing whitespace ok */
+  /* Trailing whitespace ok.  */
   * rx++ = '['; 
   * rx++ = ' '; 
   * rx++ = '\t'; 
   * rx++ = ']'; 
   * rx++ = '*'; 
 
   * rx++ = '['; 
   * rx++ = ' '; 
   * rx++ = '\t'; 
   * rx++ = ']'; 
   * rx++ = '*'; 
 
-  /* but anchor it after that */
+  /* But anchor it after that.  */
   * rx++ = '$'; 
   * rx = '\0';
 
   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
   * rx++ = '$'; 
   * rx = '\0';
 
   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
-  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB|REG_ICASE);
+  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
 
   if (reg_err == 0) 
     return NULL;
   else
     {
       static char msg[80];
 
   if (reg_err == 0) 
     return NULL;
   else
     {
       static char msg[80];
+
       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
       regfree ((regex_t *) CGEN_INSN_RX (insn));
       free (CGEN_INSN_RX (insn));
       (CGEN_INSN_RX (insn)) = NULL;
       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
       regfree ((regex_t *) CGEN_INSN_RX (insn));
       free (CGEN_INSN_RX (insn));
       (CGEN_INSN_RX (insn)) = NULL;
-    return msg;
+      return msg;
     }
 }
 
     }
 }
 
@@ -452,15 +476,13 @@ fr30_cgen_build_insn_regex (insn)
    but that can be handled there.  Not handling backtracking here may get
    expensive in the case of the m68k.  Deal with later.
 
    but that can be handled there.  Not handling backtracking here may get
    expensive in the case of the m68k.  Deal with later.
 
-   Returns NULL for success, an error message for failure.
-*/
+   Returns NULL for success, an error message for failure.  */
 
 static const char *
 
 static const char *
-parse_insn_normal (cd, insn, strp, fields)
-     CGEN_CPU_DESC cd;
-     const CGEN_INSN *insn;
-     const char **strp;
-     CGEN_FIELDS *fields;
+parse_insn_normal (CGEN_CPU_DESC cd,
+                  const CGEN_INSN *insn,
+                  const char **strp,
+                  CGEN_FIELDS *fields)
 {
   /* ??? Runtime added insns not handled yet.  */
   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
 {
   /* ??? Runtime added insns not handled yet.  */
   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
@@ -478,14 +500,14 @@ parse_insn_normal (cd, insn, strp, fields)
      GAS's input scrubber will ensure mnemonics are lowercase, but we may
      not be called from GAS.  */
   p = CGEN_INSN_MNEMONIC (insn);
      GAS's input scrubber will ensure mnemonics are lowercase, but we may
      not be called from GAS.  */
   p = CGEN_INSN_MNEMONIC (insn);
-  while (*p && tolower (*p) == tolower (*str))
+  while (*p && TOLOWER (*p) == TOLOWER (*str))
     ++p, ++str;
 
   if (* p)
     return _("unrecognized instruction");
 
 #ifndef CGEN_MNEMONIC_OPERANDS
     ++p, ++str;
 
   if (* p)
     return _("unrecognized instruction");
 
 #ifndef CGEN_MNEMONIC_OPERANDS
-  if (* str && !isspace (* str))
+  if (* str && ! ISSPACE (* str))
     return _("unrecognized instruction");
 #endif
 
     return _("unrecognized instruction");
 #endif
 
@@ -514,7 +536,7 @@ parse_insn_normal (cd, insn, strp, fields)
             first char after the mnemonic part is a space.  */
          /* FIXME: We also take inappropriate advantage of the fact that
             GAS's input scrubber will remove extraneous blanks.  */
             first char after the mnemonic part is a space.  */
          /* FIXME: We also take inappropriate advantage of the fact that
             GAS's input scrubber will remove extraneous blanks.  */
-         if (tolower (*str) == tolower (CGEN_SYNTAX_CHAR (* syn)))
+         if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
            {
 #ifdef CGEN_MNEMONIC_OPERANDS
              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
            {
 #ifdef CGEN_MNEMONIC_OPERANDS
              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
@@ -527,6 +549,7 @@ parse_insn_normal (cd, insn, strp, fields)
            {
              /* Syntax char didn't match.  Can't be this insn.  */
              static char msg [80];
            {
              /* Syntax char didn't match.  Can't be this insn.  */
              static char msg [80];
+
              /* xgettext:c-format */
              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
                       CGEN_SYNTAX_CHAR(*syn), *str);
              /* xgettext:c-format */
              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
                       CGEN_SYNTAX_CHAR(*syn), *str);
@@ -536,6 +559,7 @@ parse_insn_normal (cd, insn, strp, fields)
            {
              /* Ran out of input.  */
              static char msg [80];
            {
              /* Ran out of input.  */
              static char msg [80];
+
              /* xgettext:c-format */
              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
                       CGEN_SYNTAX_CHAR(*syn));
              /* xgettext:c-format */
              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
                       CGEN_SYNTAX_CHAR(*syn));
@@ -545,7 +569,7 @@ parse_insn_normal (cd, insn, strp, fields)
        }
 
       /* We have an operand of some sort.  */
        }
 
       /* We have an operand of some sort.  */
-      errmsg = fr30_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
+      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
                                          &str, fields);
       if (errmsg)
        return errmsg;
                                          &str, fields);
       if (errmsg)
        return errmsg;
@@ -561,7 +585,7 @@ parse_insn_normal (cd, insn, strp, fields)
         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).  */
         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))
+      while (ISSPACE (* str))
        ++ str;
 
       if (* str != '\0')
        ++ str;
 
       if (* str != '\0')
@@ -596,12 +620,11 @@ parse_insn_normal (cd, insn, strp, fields)
    mind helps keep the design clean.  */
 
 const CGEN_INSN *
    mind helps keep the design clean.  */
 
 const CGEN_INSN *
-fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
-     CGEN_CPU_DESC cd;
-     const char *str;
-     CGEN_FIELDS *fields;
-     CGEN_INSN_BYTES_PTR buf;
-     char **errmsg;
+fr30_cgen_assemble_insn (CGEN_CPU_DESC cd,
+                          const char *str,
+                          CGEN_FIELDS *fields,
+                          CGEN_INSN_BYTES_PTR buf,
+                          char **errmsg)
 {
   const char *start;
   CGEN_INSN_LIST *ilist;
 {
   const char *start;
   CGEN_INSN_LIST *ilist;
@@ -610,7 +633,7 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
   int recognized_mnemonic = 0;
 
   /* Skip leading white space.  */
   int recognized_mnemonic = 0;
 
   /* Skip leading white space.  */
-  while (isspace (* str))
+  while (ISSPACE (* str))
     ++ str;
 
   /* The instructions are stored in hashed lists.
     ++ str;
 
   /* The instructions are stored in hashed lists.
@@ -618,7 +641,6 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
 
   /* Keep looking until we find a match.  */
   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
 
   /* Keep looking until we find a match.  */
-
   start = str;
   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
     {
   start = str;
   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
     {
@@ -626,21 +648,21 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
       recognized_mnemonic = 1;
 
 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
       recognized_mnemonic = 1;
 
 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
-      /* not usually needed as unsupported opcodes shouldn't be in the hash lists */
+      /* Not usually needed as unsupported opcodes
+        shouldn't be in the hash lists.  */
       /* Is this insn supported by the selected cpu?  */
       if (! fr30_cgen_insn_supported (cd, insn))
        continue;
 #endif
       /* Is this insn supported by the selected cpu?  */
       if (! fr30_cgen_insn_supported (cd, insn))
        continue;
 #endif
-
-      /* If the RELAX attribute is set, this is an insn that shouldn't be
+      /* If the RELAXED attribute is set, this is an insn that shouldn't be
         chosen immediately.  Instead, it is used during assembler/linker
         relaxation if possible.  */
         chosen immediately.  Instead, it is used during assembler/linker
         relaxation if possible.  */
-      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
+      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
        continue;
 
       str = start;
 
        continue;
 
       str = start;
 
-      /* skip this insn if str doesn't look right lexically */
+      /* Skip this insn if str doesn't look right lexically.  */
       if (CGEN_INSN_RX (insn) != NULL &&
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
        continue;
       if (CGEN_INSN_RX (insn) != NULL &&
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
        continue;
@@ -652,7 +674,7 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
       if (parse_errmsg != NULL)
        continue;
 
       if (parse_errmsg != NULL)
        continue;
 
-      /* ??? 0 is passed for `pc' */
+      /* ??? 0 is passed for `pc' */
       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
                                                 (bfd_vma) 0);
       if (insert_errmsg != NULL)
       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
                                                 (bfd_vma) 0);
       if (insert_errmsg != NULL)
@@ -669,10 +691,11 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
     const char *tmp_errmsg;
 
     /* If requesting verbose error messages, use insert_errmsg.
     const char *tmp_errmsg;
 
     /* If requesting verbose error messages, use insert_errmsg.
-       Failing that, use parse_errmsg */
+       Failing that, use parse_errmsg */
     tmp_errmsg = (insert_errmsg ? insert_errmsg :
                  parse_errmsg ? parse_errmsg :
     tmp_errmsg = (insert_errmsg ? insert_errmsg :
                  parse_errmsg ? parse_errmsg :
-                 recognized_mnemonic ? _("unrecognized form of instruction") :
+                 recognized_mnemonic ?
+                 _("unrecognized form of instruction") :
                  _("unrecognized instruction"));
 
     if (strlen (start) > 50)
                  _("unrecognized instruction"));
 
     if (strlen (start) > 50)
@@ -705,9 +728,7 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
    FIXME: Not currently used.  */
 
 void
    FIXME: Not currently used.  */
 
 void
-fr30_cgen_asm_hash_keywords (cd, opvals)
-     CGEN_CPU_DESC cd;
-     CGEN_KEYWORD *opvals;
+fr30_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
 {
   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
   const CGEN_KEYWORD_ENTRY * ke;
 {
   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
   const CGEN_KEYWORD_ENTRY * ke;
This page took 0.029528 seconds and 4 git commands to generate.