mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-02 02:35:00 +08:00
2001-07-12 Jeff Johnston <jjohnstn@redhat.com>
* cgen-asm.in: Include "xregex.h" always to enable the libiberty regex support. (@arch@_cgen_build_insn_regex): New routine from Graydon. (@arch@_cgen_assemble_insn): Add Graydon's code to use regex to verify if it is worth parsing the insn as insn "x". Also update error message when insn is not a recognized format of the insn vs when the insn is completely unrecognized.
This commit is contained in:
@ -1,3 +1,13 @@
|
||||
2001-07-12 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* cgen-asm.in: Include "xregex.h" always to enable the libiberty
|
||||
regex support.
|
||||
(@arch@_cgen_build_insn_regex): New routine from Graydon.
|
||||
(@arch@_cgen_assemble_insn): Add Graydon's code to use regex
|
||||
to verify if it is worth parsing the insn as insn "x". Also update
|
||||
error message when insn is not a recognized format of the insn vs
|
||||
when the insn is completely unrecognized.
|
||||
|
||||
2001-07-11 Frank Ch. Eigler <fche@redhat.com>
|
||||
|
||||
* cgen-dis.in (print_insn): Use cgen_get_insn_value instead of
|
||||
|
@ -34,6 +34,7 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "@prefix@-desc.h"
|
||||
#include "@prefix@-opc.h"
|
||||
#include "opintl.h"
|
||||
#include "xregex.h"
|
||||
|
||||
#undef min
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
@ -44,6 +45,104 @@ static const char * parse_insn_normal
|
||||
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
|
||||
|
||||
/* -- assembler routines inserted here */
|
||||
|
||||
|
||||
/*
|
||||
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 @arch@_cgen_assemble_insn
|
||||
|
||||
returns NULL for success, an error message for failure
|
||||
*/
|
||||
|
||||
char *
|
||||
@arch@_cgen_build_insn_regex (insn)
|
||||
CGEN_INSN *insn;
|
||||
{
|
||||
CGEN_OPCODE *opc = 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;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* copy any remaining literals from the syntax string into the rx */
|
||||
for(; * syn != 0 && rx < rxbuf + (CGEN_MAX_RX_ELEMENTS - 9); ++syn, ++rx)
|
||||
{
|
||||
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 '$':
|
||||
|
||||
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
|
||||
case '?': case '{': case '}':
|
||||
case '(': case ')': case '*':
|
||||
case '|': case '+': case ']':
|
||||
#endif
|
||||
|
||||
* rx++ = '\\';
|
||||
break;
|
||||
}
|
||||
/* insert syntax char into rx */
|
||||
* rx = tmp;
|
||||
}
|
||||
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|REG_ICASE);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Default insn parser.
|
||||
|
||||
@ -211,6 +310,7 @@ const CGEN_INSN *
|
||||
CGEN_INSN_LIST *ilist;
|
||||
const char *parse_errmsg = NULL;
|
||||
const char *insert_errmsg = NULL;
|
||||
int recognized_mnemonic = 0;
|
||||
|
||||
/* Skip leading white space. */
|
||||
while (isspace (* str))
|
||||
@ -226,6 +326,7 @@ const CGEN_INSN *
|
||||
for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
|
||||
{
|
||||
const CGEN_INSN *insn = ilist->insn;
|
||||
recognized_mnemonic = 1;
|
||||
|
||||
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
|
||||
/* not usually needed as unsupported opcodes shouldn't be in the hash lists */
|
||||
@ -242,6 +343,11 @@ const CGEN_INSN *
|
||||
|
||||
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);
|
||||
|
||||
@ -269,6 +375,7 @@ const CGEN_INSN *
|
||||
Failing that, use parse_errmsg */
|
||||
tmp_errmsg = (insert_errmsg ? insert_errmsg :
|
||||
parse_errmsg ? parse_errmsg :
|
||||
recognized_mnemonic ? _("unrecognized form of instruction") :
|
||||
_("unrecognized instruction"));
|
||||
|
||||
if (strlen (start) > 50)
|
||||
|
Reference in New Issue
Block a user