XCOFF booke tests. Fix tlbre, tlbwe ppc WS field.
[deliverable/binutils-gdb.git] / opcodes / fr30-asm.c
index 9ad3f2c5be38dd8b49c73579b1c3d55685f2d69a..40f015ad0358519639c294e15745872d7a1f4ae0 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"
@@ -35,19 +34,34 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
 #include "fr30-opc.h"
 #include "opintl.h"
 #include "xregex.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)
@@ -55,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;
 
@@ -70,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 != ')')
     {
@@ -96,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;
@@ -157,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
@@ -168,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)
@@ -180,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)
     {
@@ -327,26 +344,23 @@ 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 * 
 fr30_cgen_build_insn_regex (insn)
      CGEN_INSN *insn;
 {  
 
 char * 
 fr30_cgen_build_insn_regex (insn)
      CGEN_INSN *insn;
 {  
-  CGEN_OPCODE *opc = CGEN_INSN_OPCODE (insn);
+  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
   const char *mnem = CGEN_INSN_MNEMONIC (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;
@@ -354,72 +368,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;
     }
 }
 
     }
 }
 
@@ -435,8 +477,7 @@ 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 *
 parse_insn_normal (cd, insn, strp, fields)
 
 static const char *
 parse_insn_normal (cd, insn, strp, fields)
@@ -461,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
 
@@ -497,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) == ' ')
@@ -510,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);
@@ -519,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));
@@ -544,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')
@@ -593,7 +636,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.
@@ -601,7 +644,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))
     {
@@ -609,12 +651,12 @@ 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
         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.  */
@@ -623,7 +665,7 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
 
       str = start;
 
 
       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;
@@ -635,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)
@@ -652,10 +694,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)
This page took 0.028319 seconds and 4 git commands to generate.