Ignore:
Timestamp:
Aug 16, 2003, 6:59:22 PM (22 years ago)
Author:
bird
Message:

binutils v2.14 - offical sources.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/binutils/opcodes/m32r-asm.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r608 r609  
    2727
    2828#include "sysdep.h"
    29 #include <ctype.h>
    3029#include <stdio.h>
    3130#include "ansidecl.h"
     
    3534#include "m32r-opc.h"
    3635#include "opintl.h"
    37 
    38 #undef min
     36#include "xregex.h"
     37#include "libiberty.h"
     38#include "safe-ctype.h"
     39
     40#undef  min
    3941#define min(a,b) ((a) < (b) ? (a) : (b))
    40 #undef max
     42#undef  max
    4143#define max(a,b) ((a) > (b) ? (a) : (b))
    4244
     
    4547
    4648
    47 /* -- assembler routines inserted here */
     49/* -- assembler routines inserted here. */
    4850
    4951/* -- asm.c */
     52static const char * parse_hash
     53  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
     54static const char * parse_hi16
     55  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
     56static const char * parse_slo16
     57  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
     58static const char * parse_ulo16
     59  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
    5060
    5161/* Handle '#' prefixes (i.e. skip over them).  */
     
    5363static const char *
    5464parse_hash (cd, strp, opindex, valuep)
    55      CGEN_CPU_DESC cd;
     65     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
    5666     const char **strp;
    57      int opindex;
    58      unsigned long *valuep;
     67     int opindex ATTRIBUTE_UNUSED;
     68     unsigned long *valuep ATTRIBUTE_UNUSED;
    5969{
    6070  if (**strp == '#')
     
    197207/* -- */
    198208
     209const char * m32r_cgen_parse_operand
     210  PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
     211
    199212/* Main entry point for operand parsing.
    200213
     
    208221   This function could be moved into `parse_insn_normal', but keeping it
    209222   separate makes clear the interface between `parse_insn_normal' and each of
    210    the handlers.
    211 */
     223   the handlers.  */
    212224
    213225const char *
     
    220232  const char * errmsg = NULL;
    221233  /* Used by scalar operands that still need to be parsed.  */
    222   long junk;
     234  long junk ATTRIBUTE_UNUSED;
    223235
    224236  switch (opindex)
     
    336348
    337349
     350
     351/* Regex construction routine.
     352
     353   This translates an opcode syntax string into a regex string,
     354   by replacing any non-character syntax element (such as an
     355   opcode) with the pattern '.*'
     356
     357   It then compiles the regex and stores it in the opcode, for
     358   later use by m32r_cgen_assemble_insn
     359
     360   Returns NULL for success, an error message for failure.  */
     361
     362char *
     363m32r_cgen_build_insn_regex (insn)
     364     CGEN_INSN *insn;
     365
     366  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
     367  const char *mnem = CGEN_INSN_MNEMONIC (insn);
     368  char rxbuf[CGEN_MAX_RX_ELEMENTS];
     369  char *rx = rxbuf;
     370  const CGEN_SYNTAX_CHAR_TYPE *syn;
     371  int reg_err;
     372
     373  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
     374
     375  /* Mnemonics come first in the syntax string.  */
     376  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
     377    return _("missing mnemonic in syntax string");
     378  ++syn;
     379
     380  /* Generate a case sensitive regular expression that emulates case
     381     insensitive matching in the "C" locale.  We cannot generate a case
     382     insensitive regular expression because in Turkish locales, 'i' and 'I'
     383     are not equal modulo case conversion.  */
     384
     385  /* Copy the literal mnemonic out of the insn.  */
     386  for (; *mnem; mnem++)
     387    {
     388      char c = *mnem;
     389
     390      if (ISALPHA (c))
     391        {
     392          *rx++ = '[';
     393          *rx++ = TOLOWER (c);
     394          *rx++ = TOUPPER (c);
     395          *rx++ = ']';
     396        }
     397      else
     398        *rx++ = c;
     399    }
     400
     401  /* Copy any remaining literals from the syntax string into the rx.  */
     402  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
     403    {
     404      if (CGEN_SYNTAX_CHAR_P (* syn))
     405        {
     406          char c = CGEN_SYNTAX_CHAR (* syn);
     407
     408          switch (c)
     409            {
     410              /* Escape any regex metacharacters in the syntax.  */
     411            case '.': case '[': case '\\':
     412            case '*': case '^': case '$':
     413
     414#ifdef CGEN_ESCAPE_EXTENDED_REGEX
     415            case '?': case '{': case '}':
     416            case '(': case ')': case '*':
     417            case '|': case '+': case ']':
     418#endif
     419              *rx++ = '\\';
     420              *rx++ = c;
     421              break;
     422
     423            default:
     424              if (ISALPHA (c))
     425                {
     426                  *rx++ = '[';
     427                  *rx++ = TOLOWER (c);
     428                  *rx++ = TOUPPER (c);
     429                  *rx++ = ']';
     430                }
     431              else
     432                *rx++ = c;
     433              break;
     434            }
     435        }
     436      else
     437        {
     438          /* Replace non-syntax fields with globs.  */
     439          *rx++ = '.';
     440          *rx++ = '*';
     441        }
     442    }
     443
     444  /* Trailing whitespace ok.  */
     445  * rx++ = '[';
     446  * rx++ = ' ';
     447  * rx++ = '\t';
     448  * rx++ = ']';
     449  * rx++ = '*';
     450
     451  /* But anchor it after that.  */
     452  * rx++ = '$';
     453  * rx = '\0';
     454
     455  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
     456  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
     457
     458  if (reg_err == 0)
     459    return NULL;
     460  else
     461    {
     462      static char msg[80];
     463
     464      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
     465      regfree ((regex_t *) CGEN_INSN_RX (insn));
     466      free (CGEN_INSN_RX (insn));
     467      (CGEN_INSN_RX (insn)) = NULL;
     468      return msg;
     469    }
     470}
     471
     472
     473
    338474/* Default insn parser.
    339475
     
    347483   expensive in the case of the m68k.  Deal with later.
    348484
    349    Returns NULL for success, an error message for failure.
    350 */
     485   Returns NULL for success, an error message for failure.  */
    351486
    352487static const char *
     
    362497  const char *errmsg;
    363498  const char *p;
    364   const unsigned char * syn;
     499  const CGEN_SYNTAX_CHAR_TYPE * syn;
    365500#ifdef CGEN_MNEMONIC_OPERANDS
    366501  /* FIXME: wip */
     
    373508     not be called from GAS.  */
    374509  p = CGEN_INSN_MNEMONIC (insn);
    375   while (*p && tolower (*p) == tolower (*str))
     510  while (*p && TOLOWER (*p) == TOLOWER (*str))
    376511    ++p, ++str;
    377512
     
    380515
    381516#ifndef CGEN_MNEMONIC_OPERANDS
    382   if (* str && !isspace (* str))
     517  if (* str && ! ISSPACE (* str))
    383518    return _("unrecognized instruction");
    384519#endif
     
    409544          /* FIXME: We also take inappropriate advantage of the fact that
    410545             GAS's input scrubber will remove extraneous blanks.  */
    411           if (tolower (*str) == tolower (CGEN_SYNTAX_CHAR (* syn)))
     546          if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
    412547            {
    413548#ifdef CGEN_MNEMONIC_OPERANDS
    414               if (* syn == ' ')
     549              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
    415550                past_opcode_p = 1;
    416551#endif
     
    418553              ++ str;
    419554            }
    420           else
     555          else if (*str)
    421556            {
    422557              /* Syntax char didn't match.  Can't be this insn.  */
    423558              static char msg [80];
     559
    424560              /* xgettext:c-format */
    425561              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
    426                        *syn, *str);
     562                       CGEN_SYNTAX_CHAR(*syn), *str);
     563              return msg;
     564            }
     565          else
     566            {
     567              /* Ran out of input.  */
     568              static char msg [80];
     569
     570              /* xgettext:c-format */
     571              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
     572                       CGEN_SYNTAX_CHAR(*syn));
    427573              return msg;
    428574            }
     
    431577
    432578      /* We have an operand of some sort.  */
    433       errmsg = m32r_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
     579      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
    434580                                          &str, fields);
    435581      if (errmsg)
     
    441587
    442588  /* If we're at the end of the syntax string, we're done.  */
    443   if (* syn == '\0')
     589  if (* syn == 0)
    444590    {
    445591      /* FIXME: For the moment we assume a valid `str' can only contain
     
    447593         the insn and it is assumed that longer versions of insns appear
    448594         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
    449       while (isspace (* str))
     595      while (ISSPACE (* str))
    450596        ++ str;
    451597
     
    492638  const char *start;
    493639  CGEN_INSN_LIST *ilist;
    494   const char *tmp_errmsg = NULL;
     640  const char *parse_errmsg = NULL;
     641  const char *insert_errmsg = NULL;
     642  int recognized_mnemonic = 0;
    495643
    496644  /* Skip leading white space.  */
    497   while (isspace (* str))
     645  while (ISSPACE (* str))
    498646    ++ str;
    499647
     
    503651
    504652  /* Keep looking until we find a match.  */
    505 
    506653  start = str;
    507654  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
    508655    {
    509656      const CGEN_INSN *insn = ilist->insn;
     657      recognized_mnemonic = 1;
    510658
    511659#ifdef CGEN_VALIDATE_INSN_SUPPORTED
    512       /* not usually needed as unsupported opcodes shouldn't be in the hash lists */
     660      /* Not usually needed as unsupported opcodes
     661         shouldn't be in the hash lists.  */
    513662      /* Is this insn supported by the selected cpu?  */
    514663      if (! m32r_cgen_insn_supported (cd, insn))
    515664        continue;
    516665#endif
    517 
    518666      /* If the RELAX attribute is set, this is an insn that shouldn't be
    519667         chosen immediately.  Instead, it is used during assembler/linker
     
    524672      str = start;
    525673
     674      /* Skip this insn if str doesn't look right lexically.  */
     675      if (CGEN_INSN_RX (insn) != NULL &&
     676          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
     677        continue;
     678
    526679      /* Allow parse/insert handlers to obtain length of insn.  */
    527680      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
    528681
    529       tmp_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
    530       if (tmp_errmsg != NULL)
     682      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
     683      if (parse_errmsg != NULL)
    531684        continue;
    532685
    533       /* ??? 0 is passed for `pc' */
    534       tmp_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
    535                                               (bfd_vma) 0);
    536       if (tmp_errmsg != NULL)
     686      /* ??? 0 is passed for `pc'. */
     687      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
     688                                                (bfd_vma) 0);
     689      if (insert_errmsg != NULL)
    537690        continue;
    538691
     
    542695    }
    543696
    544   /* Make sure we leave this with something at this point. */
    545   if (tmp_errmsg == NULL)
    546     tmp_errmsg = "unknown mnemonic";
    547 
    548697  {
    549698    static char errbuf[150];
    550 
    551699#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
    552     /* if verbose error messages, use errmsg from CGEN_PARSE_FN */
     700    const char *tmp_errmsg;
     701
     702    /* If requesting verbose error messages, use insert_errmsg.
     703       Failing that, use parse_errmsg.  */
     704    tmp_errmsg = (insert_errmsg ? insert_errmsg :
     705                  parse_errmsg ? parse_errmsg :
     706                  recognized_mnemonic ?
     707                  _("unrecognized form of instruction") :
     708                  _("unrecognized instruction"));
     709
    553710    if (strlen (start) > 50)
    554711      /* xgettext:c-format */
Note: See TracChangeset for help on using the changeset viewer.