XCOFF booke tests. Fix tlbre, tlbwe ppc WS field.
[deliverable/binutils-gdb.git] / opcodes / fr30-asm.c
index 05e72aa80037a8c3f6e99d76d2b750981f6337cf..40f015ad0358519639c294e15745872d7a1f4ae0 100644 (file)
@@ -4,7 +4,7 @@
 THIS FILE IS MACHINE GENERATED WITH CGEN.
 - the resultant file is machine generated, cgen-asm.in isn't
 
 THIS FILE IS MACHINE GENERATED WITH CGEN.
 - the resultant file is machine generated, cgen-asm.in isn't
 
-Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
+Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of the GNU Binutils and GDB, the GNU debugger.
 
 
 This file is part of the GNU Binutils and GDB, the GNU debugger.
 
@@ -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"
@@ -34,19 +33,35 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
 #include "fr30-desc.h"
 #include "fr30-opc.h"
 #include "opintl.h"
 #include "fr30-desc.h"
 #include "fr30-opc.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
      PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
 \f
 #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 *));
 \f
-/* -- assembler routines inserted here */
+/* -- assembler routines inserted here */
 
 /* -- asm.c */
 
 /* -- asm.c */
-/* Handle register lists for LDMx and STMx  */
+/* Handle register lists for LDMx and STMx.  */
+
+static int parse_register_number
+  PARAMS ((const char **));
+static const char * parse_register_list
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *, int, int));
+static const char * parse_low_register_list_ld
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+static const char * parse_hi_register_list_ld
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+static const char * parse_low_register_list_st
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+static const char * parse_hi_register_list_st
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
 
 static int
 parse_register_number (strp)
 
 static int
 parse_register_number (strp)
@@ -54,7 +69,7 @@ parse_register_number (strp)
 {
   int regno;
   if (**strp < '0' || **strp > '9')
 {
   int regno;
   if (**strp < '0' || **strp > '9')
-    return -1; /* error */
+    return -1; /* error */
   regno = **strp - '0';
   ++*strp;
 
   regno = **strp - '0';
   ++*strp;
 
@@ -69,14 +84,15 @@ parse_register_number (strp)
 
 static const char *
 parse_register_list (cd, strp, opindex, valuep, high_low, load_store)
 
 static const char *
 parse_register_list (cd, strp, opindex, valuep, high_low, load_store)
-     CGEN_CPU_DESC cd;
+     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
      const char **strp;
      const char **strp;
-     int opindex;
+     int opindex ATTRIBUTE_UNUSED;
      unsigned long *valuep;
      int high_low;   /* 0 == high, 1 == low */
      int load_store; /* 0 == load, 1 == store */
 {
   int regno;
      unsigned long *valuep;
      int high_low;   /* 0 == high, 1 == low */
      int load_store; /* 0 == load, 1 == store */
 {
   int regno;
+
   *valuep = 0;
   while (**strp && **strp != ')')
     {
   *valuep = 0;
   while (**strp && **strp != ')')
     {
@@ -95,7 +111,7 @@ parse_register_list (cd, strp, opindex, valuep, high_low, load_store)
       if (high_low)
        regno -= 8;
 
       if (high_low)
        regno -= 8;
 
-      if (load_store) /* mask is reversed for store */
+      if (load_store) /* Mask is reversed for store.  */
        *valuep |= 0x80 >> regno;
       else
        *valuep |= 1 << regno;
        *valuep |= 0x80 >> regno;
       else
        *valuep |= 1 << regno;
@@ -156,6 +172,9 @@ parse_hi_register_list_st (cd, strp, opindex, valuep)
 
 /* -- */
 
 
 /* -- */
 
+const char * fr30_cgen_parse_operand
+  PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
+
 /* Main entry point for operand parsing.
 
    This function is basically just a big switch statement.  Earlier versions
 /* Main entry point for operand parsing.
 
    This function is basically just a big switch statement.  Earlier versions
@@ -167,8 +186,7 @@ parse_hi_register_list_st (cd, strp, opindex, valuep)
 
    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)
@@ -179,7 +197,7 @@ fr30_cgen_parse_operand (cd, opindex, strp, fields)
 {
   const char * errmsg = NULL;
   /* Used by scalar operands that still need to be parsed.  */
 {
   const char * errmsg = NULL;
   /* Used by scalar operands that still need to be parsed.  */
-  long junk;
+  long junk ATTRIBUTE_UNUSED;
 
   switch (opindex)
     {
 
   switch (opindex)
     {
@@ -324,6 +342,129 @@ fr30_cgen_init_asm (cd)
   cd->parse_operand = fr30_cgen_parse_operand;
 }
 
   cd->parse_operand = fr30_cgen_parse_operand;
 }
 
+\f
+
+/* 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 '.*'
+
+   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.  */
+
+char * 
+fr30_cgen_build_insn_regex (insn)
+     CGEN_INSN *insn;
+{  
+  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
+  const char *mnem = CGEN_INSN_MNEMONIC (insn);
+  char rxbuf[CGEN_MAX_RX_ELEMENTS];
+  char *rx = rxbuf;
+  const CGEN_SYNTAX_CHAR_TYPE *syn;
+  int reg_err;
+
+  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");
+  ++syn;
+
+  /* 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 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)) 
+       {
+         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
+           case '?': case '{': case '}': 
+           case '(': case ')': case '*':
+           case '|': case '+': case ']':
+#endif
+             *rx++ = '\\';
+             *rx++ = c;
+             break;
+
+           default:
+             if (ISALPHA (c))
+               {
+                 *rx++ = '[';
+                 *rx++ = TOLOWER (c);
+                 *rx++ = TOUPPER (c);
+                 *rx++ = ']';
+               }
+             else
+               *rx++ = c;
+             break;
+           }
+       }
+      else
+       {
+         /* Replace non-syntax fields with globs.  */
+         *rx++ = '.';
+         *rx++ = '*';
+       }
+    }
+
+  /* Trailing whitespace ok.  */
+  * rx++ = '['; 
+  * rx++ = ' '; 
+  * rx++ = '\t'; 
+  * rx++ = ']'; 
+  * rx++ = '*'; 
+
+  /* But anchor it after that.  */
+  * rx++ = '$'; 
+  * rx = '\0';
+
+  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
+  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
+
+  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;
+      return msg;
+    }
+}
+
 \f
 /* Default insn parser.
 
 \f
 /* Default insn parser.
 
@@ -336,8 +477,7 @@ fr30_cgen_init_asm (cd)
    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 *
 parse_insn_normal (cd, insn, strp, fields)
 
 static const char *
 parse_insn_normal (cd, insn, strp, fields)
@@ -362,14 +502,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
 
@@ -398,7 +538,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) == ' ')
@@ -411,6 +551,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);
@@ -420,6 +561,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));
@@ -445,7 +587,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')
@@ -491,9 +633,10 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
   CGEN_INSN_LIST *ilist;
   const char *parse_errmsg = NULL;
   const char *insert_errmsg = NULL;
   CGEN_INSN_LIST *ilist;
   const char *parse_errmsg = NULL;
   const char *insert_errmsg = NULL;
+  int recognized_mnemonic = 0;
 
   /* Skip leading white space.  */
 
   /* 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.
@@ -501,19 +644,19 @@ 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))
     {
       const CGEN_INSN *insn = ilist->insn;
   start = str;
   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
     {
       const CGEN_INSN *insn = ilist->insn;
+      recognized_mnemonic = 1;
 
 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
 
 #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
         chosen immediately.  Instead, it is used during assembler/linker
         relaxation if possible.  */
       /* If the RELAX attribute is set, this is an insn that shouldn't be
         chosen immediately.  Instead, it is used during assembler/linker
         relaxation if possible.  */
@@ -522,6 +665,11 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
 
       str = start;
 
 
       str = start;
 
+      /* 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;
+
       /* Allow parse/insert handlers to obtain length of insn.  */
       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
 
       /* Allow parse/insert handlers to obtain length of insn.  */
       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
 
@@ -529,7 +677,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)
@@ -542,13 +690,15 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
 
   {
     static char errbuf[150];
 
   {
     static char errbuf[150];
+#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
     const char *tmp_errmsg;
 
     const char *tmp_errmsg;
 
-#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
     /* If requesting verbose error messages, use insert_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") :
                  _("unrecognized instruction"));
 
     if (strlen (start) > 50)
                  _("unrecognized instruction"));
 
     if (strlen (start) > 50)
This page took 0.030955 seconds and 4 git commands to generate.