* cgen-ibld.in (extract_normal): Match type of VALUE and MASK

to *VALUEP.  Regenerate all cgen files.
This commit is contained in:
Richard Henderson 2001-08-12 20:16:29 +00:00
parent d8b6305a45
commit fc7bc88384
18 changed files with 624 additions and 138 deletions

View File

@ -1,3 +1,8 @@
2001-08-12 Richard Henderson <rth@redhat.com>
* cgen-ibld.in (extract_normal): Match type of VALUE and MASK
to *VALUEP. Regenerate all cgen files.
2001-08-10 Richard Sandiford <rsandifo@redhat.com>
* mips-dis.c (print_insn_mips): Remove OPCODE_IS_MEMBER's gp32

View File

@ -415,7 +415,7 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
#endif
long *valuep;
{
CGEN_INSN_INT value, mask;
long value, mask;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */

View File

@ -34,6 +34,7 @@ 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 "xregex.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
@ -324,6 +325,104 @@ fr30_cgen_init_asm (cd)
cd->parse_operand = fr30_cgen_parse_operand;
}
/*
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_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.
@ -491,6 +590,7 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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))
@ -506,6 +606,7 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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 */
@ -522,6 +623,11 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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);
@ -542,13 +648,14 @@ fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
{
static char errbuf[150];
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
const char *tmp_errmsg;
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
/* If requesting verbose error messages, use insert_errmsg.
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)

View File

@ -122,8 +122,8 @@ static const CGEN_ISA fr30_cgen_isa_table[] = {
/* Machine variants. */
static const CGEN_MACH fr30_cgen_mach_table[] = {
{ "fr30", "fr30", MACH_FR30 },
{ 0, 0, 0 }
{ "fr30", "fr30", MACH_FR30, 0 },
{ 0, 0, 0, 0 }
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_gr_names_entries[] =
@ -153,7 +153,7 @@ CGEN_KEYWORD fr30_cgen_opval_gr_names =
{
& fr30_cgen_opval_gr_names_entries[0],
19,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_cr_names_entries[] =
@ -180,7 +180,7 @@ CGEN_KEYWORD fr30_cgen_opval_cr_names =
{
& fr30_cgen_opval_cr_names_entries[0],
16,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_dr_names_entries[] =
@ -197,7 +197,7 @@ CGEN_KEYWORD fr30_cgen_opval_dr_names =
{
& fr30_cgen_opval_dr_names_entries[0],
6,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_ps_entries[] =
@ -209,7 +209,7 @@ CGEN_KEYWORD fr30_cgen_opval_h_ps =
{
& fr30_cgen_opval_h_ps_entries[0],
1,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_r13_entries[] =
@ -221,7 +221,7 @@ CGEN_KEYWORD fr30_cgen_opval_h_r13 =
{
& fr30_cgen_opval_h_r13_entries[0],
1,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_r14_entries[] =
@ -233,7 +233,7 @@ CGEN_KEYWORD fr30_cgen_opval_h_r14 =
{
& fr30_cgen_opval_h_r14_entries[0],
1,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_r15_entries[] =
@ -245,7 +245,7 @@ CGEN_KEYWORD fr30_cgen_opval_h_r15 =
{
& fr30_cgen_opval_h_r15_entries[0],
1,
0, 0, 0, 0
0, 0, 0, 0, ""
};
@ -1476,11 +1476,9 @@ static void
fr30_cgen_rebuild_tables (cd)
CGEN_CPU_TABLE *cd;
{
int i,n_isas;
int i;
unsigned int isas = cd->isas;
#if 0
unsigned int machs = cd->machs;
#endif
cd->int_insn_p = CGEN_INT_INSN_P;
@ -1518,20 +1516,26 @@ fr30_cgen_rebuild_tables (cd)
cd->min_insn_bitsize = isa->min_insn_bitsize;
if (isa->max_insn_bitsize > cd->max_insn_bitsize)
cd->max_insn_bitsize = isa->max_insn_bitsize;
++n_isas;
}
#if 0 /* Does nothing?? */
/* Data derived from the mach spec. */
for (i = 0; i < MAX_MACHS; ++i)
if (((1 << i) & machs) != 0)
{
const CGEN_MACH *mach = & fr30_cgen_mach_table[i];
++n_machs;
if (mach->insn_chunk_bitsize != 0)
{
if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
{
fprintf (stderr, "fr30_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
abort ();
}
cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
}
}
#endif
/* Determine which hw elements are used by MACH. */
build_hw_table (cd);

View File

@ -495,13 +495,19 @@ print_insn (cd, pc, info, buf, buflen)
char *buf;
int buflen;
{
unsigned long insn_value;
CGEN_INSN_INT insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
int rc = read_insn (cd, pc, info, buf, buflen, & ex_info, & insn_value);
if (rc != 0)
return rc;
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
insn_value = cgen_get_insn_value (cd, buf, buflen * 8);
/* Fill in ex_info fields like read_insn would. Don't actually call
read_insn, since the incoming buffer is already read (and possibly
modified a la m32r). */
ex_info.valid = (1 << buflen) - 1;
ex_info.dis_info = info;
ex_info.insn_bytes = buf;
/* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */
@ -512,6 +518,7 @@ print_insn (cd, pc, info, buf, buflen)
const CGEN_INSN *insn = insn_list->insn;
CGEN_FIELDS fields;
int length;
unsigned long insn_value_cropped;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* not needed as insn shouldn't be in hash lists if not supported */
@ -526,7 +533,17 @@ print_insn (cd, pc, info, buf, buflen)
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
if ((insn_value & CGEN_INSN_BASE_MASK (insn))
/* Base size may exceed this instruction's size. Extract the
relevant part from the buffer. */
if ((CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
(CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
info->endian == BFD_ENDIAN_BIG);
else
insn_value_cropped = insn_value;
if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
@ -549,7 +566,7 @@ print_insn (cd, pc, info, buf, buflen)
}
else
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, insn_value, &fields, pc);
(cd, insn, &ex_info, insn_value_cropped, &fields, pc);
/* length < 0 -> error */
if (length < 0)
@ -583,18 +600,27 @@ default_print_insn (cd, pc, info)
disassemble_info *info;
{
char buf[CGEN_MAX_INSN_SIZE];
int buflen;
int status;
/* Read the base part of the insn. */
/* Attempt to read the base part of the insn. */
buflen = cd->base_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
/* Try again with the minimum part, if min < base. */
if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
{
buflen = cd->min_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
}
status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
return print_insn (cd, pc, info, buf, buflen);
}
/* Main entry point.

View File

@ -145,7 +145,22 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
}
/* Ensure VALUE will fit. */
if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
{
long minval = - (1L << (length - 1));
unsigned long maxval = mask;
if ((value > 0 && (unsigned long) value > maxval)
|| value < minval)
{
/* xgettext:c-format */
sprintf (errbuf,
_("operand out of range (%ld not between %ld and %lu)"),
value, minval, maxval);
return errbuf;
}
}
else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
{
unsigned long maxval = mask;
@ -202,10 +217,10 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
}
/* Default insn builder (insert handler).
The instruction is recorded in CGEN_INT_INSN_P byte order
(meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
recorded in host byte order, otherwise BUFFER is an array of bytes and the
value is recorded in target byte order).
The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
recorded in host byte order, otherwise BUFFER is an array of bytes
and the value is recorded in target byte order).
The result is an error message or NULL if success. */
static const char *
@ -265,7 +280,7 @@ insert_insn_normal (cd, insn, fields, buffer, pc)
static void
put_insn_int_value (cd, buf, length, insn_length, value)
CGEN_CPU_DESC cd;
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
CGEN_INSN_BYTES_PTR buf;
int length;
int insn_length;
@ -400,7 +415,7 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
#endif
long *valuep;
{
CGEN_INSN_INT value, mask;
long value, mask;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
@ -428,9 +443,9 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
word_length = total_length;
}
/* Does the value reside in INSN_VALUE? */
/* Does the value reside in INSN_VALUE, and at the right alignment? */
if (CGEN_INT_INSN_P || word_offset == 0)
if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
{
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((word_offset + start + 1) - length);

View File

@ -1368,6 +1368,7 @@ fr30_cgen_init_opcode_table (cd)
{
insns[i].base = &ib[i];
insns[i].opcode = &oc[i];
fr30_cgen_build_insn_regex (& insns[i]);
}
cd->macro_insn_table.init_entries = insns;
cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
@ -1376,7 +1377,10 @@ fr30_cgen_init_opcode_table (cd)
oc = & fr30_cgen_insn_opcode_table[0];
insns = (CGEN_INSN *) cd->insn_table.init_entries;
for (i = 0; i < MAX_INSNS; ++i)
insns[i].opcode = &oc[i];
{
insns[i].opcode = &oc[i];
fr30_cgen_build_insn_regex (& insns[i]);
}
cd->sizeof_fields = sizeof (CGEN_FIELDS);
cd->set_fields_bitsize = set_fields_bitsize;

View File

@ -34,6 +34,7 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
#include "m32r-desc.h"
#include "m32r-opc.h"
#include "opintl.h"
#include "xregex.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
@ -332,6 +333,104 @@ m32r_cgen_init_asm (cd)
cd->parse_operand = m32r_cgen_parse_operand;
}
/*
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 m32r_cgen_assemble_insn
returns NULL for success, an error message for failure
*/
char *
m32r_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.
@ -499,6 +598,7 @@ m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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))
@ -514,6 +614,7 @@ m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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 */
@ -530,6 +631,11 @@ m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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);
@ -557,6 +663,7 @@ m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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)

View File

@ -136,9 +136,9 @@ static const CGEN_ISA m32r_cgen_isa_table[] = {
/* Machine variants. */
static const CGEN_MACH m32r_cgen_mach_table[] = {
{ "m32r", "m32r", MACH_M32R },
{ "m32rx", "m32rx", MACH_M32RX },
{ 0, 0, 0 }
{ "m32r", "m32r", MACH_M32R, 0 },
{ "m32rx", "m32rx", MACH_M32RX, 0 },
{ 0, 0, 0, 0 }
};
static CGEN_KEYWORD_ENTRY m32r_cgen_opval_gr_names_entries[] =
@ -168,7 +168,7 @@ CGEN_KEYWORD m32r_cgen_opval_gr_names =
{
& m32r_cgen_opval_gr_names_entries[0],
19,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY m32r_cgen_opval_cr_names_entries[] =
@ -202,7 +202,7 @@ CGEN_KEYWORD m32r_cgen_opval_cr_names =
{
& m32r_cgen_opval_cr_names_entries[0],
23,
0, 0, 0, 0
0, 0, 0, 0, ""
};
static CGEN_KEYWORD_ENTRY m32r_cgen_opval_h_accums_entries[] =
@ -215,7 +215,7 @@ CGEN_KEYWORD m32r_cgen_opval_h_accums =
{
& m32r_cgen_opval_h_accums_entries[0],
2,
0, 0, 0, 0
0, 0, 0, 0, ""
};
@ -1200,11 +1200,9 @@ static void
m32r_cgen_rebuild_tables (cd)
CGEN_CPU_TABLE *cd;
{
int i,n_isas;
int i;
unsigned int isas = cd->isas;
#if 0
unsigned int machs = cd->machs;
#endif
cd->int_insn_p = CGEN_INT_INSN_P;
@ -1242,20 +1240,26 @@ m32r_cgen_rebuild_tables (cd)
cd->min_insn_bitsize = isa->min_insn_bitsize;
if (isa->max_insn_bitsize > cd->max_insn_bitsize)
cd->max_insn_bitsize = isa->max_insn_bitsize;
++n_isas;
}
#if 0 /* Does nothing?? */
/* Data derived from the mach spec. */
for (i = 0; i < MAX_MACHS; ++i)
if (((1 << i) & machs) != 0)
{
const CGEN_MACH *mach = & m32r_cgen_mach_table[i];
++n_machs;
if (mach->insn_chunk_bitsize != 0)
{
if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
{
fprintf (stderr, "m32r_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
abort ();
}
cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
}
}
#endif
/* Determine which hw elements are used by MACH. */
build_hw_table (cd);

View File

@ -434,12 +434,12 @@ print_insn (cd, pc, info, buf, buflen)
char *buf;
int buflen;
{
unsigned long insn_value;
CGEN_INSN_INT insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
insn_value = cgen_get_insn_value (cd, buf, buflen * 8);
/* Fill in ex_info fields like read_insn would. Don't actually call
read_insn, since the incoming buffer is already read (and possibly
@ -505,7 +505,7 @@ print_insn (cd, pc, info, buf, buflen)
}
else
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, insn_value, &fields, pc);
(cd, insn, &ex_info, insn_value_cropped, &fields, pc);
/* length < 0 -> error */
if (length < 0)
@ -539,18 +539,27 @@ default_print_insn (cd, pc, info)
disassemble_info *info;
{
char buf[CGEN_MAX_INSN_SIZE];
int buflen;
int status;
/* Read the base part of the insn. */
/* Attempt to read the base part of the insn. */
buflen = cd->base_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
/* Try again with the minimum part, if min < base. */
if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
{
buflen = cd->min_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
}
status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
return print_insn (cd, pc, info, buf, buflen);
}
/* Main entry point.

View File

@ -145,7 +145,22 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
}
/* Ensure VALUE will fit. */
if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
{
long minval = - (1L << (length - 1));
unsigned long maxval = mask;
if ((value > 0 && (unsigned long) value > maxval)
|| value < minval)
{
/* xgettext:c-format */
sprintf (errbuf,
_("operand out of range (%ld not between %ld and %lu)"),
value, minval, maxval);
return errbuf;
}
}
else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
{
unsigned long maxval = mask;
@ -400,7 +415,7 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
#endif
long *valuep;
{
CGEN_INSN_INT value, mask;
long value, mask;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
@ -428,9 +443,9 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
word_length = total_length;
}
/* Does the value reside in INSN_VALUE? */
/* Does the value reside in INSN_VALUE, and at the right alignment? */
if (CGEN_INT_INSN_P || word_offset == 0)
if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
{
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((word_offset + start + 1) - length);

View File

@ -1685,6 +1685,7 @@ m32r_cgen_init_opcode_table (cd)
{
insns[i].base = &ib[i];
insns[i].opcode = &oc[i];
m32r_cgen_build_insn_regex (& insns[i]);
}
cd->macro_insn_table.init_entries = insns;
cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
@ -1693,7 +1694,10 @@ m32r_cgen_init_opcode_table (cd)
oc = & m32r_cgen_insn_opcode_table[0];
insns = (CGEN_INSN *) cd->insn_table.init_entries;
for (i = 0; i < MAX_INSNS; ++i)
insns[i].opcode = &oc[i];
{
insns[i].opcode = &oc[i];
m32r_cgen_build_insn_regex (& insns[i]);
}
cd->sizeof_fields = sizeof (CGEN_FIELDS);
cd->set_fields_bitsize = set_fields_bitsize;

View File

@ -137,7 +137,7 @@ static const CGEN_OPINST sfmt_beqz_ops[] = {
static const CGEN_OPINST sfmt_bl8_ops[] = {
{ INPUT, "disp8", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP8), 0, 0 },
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
{ OUTPUT, "h_gr_SI_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ END }
};
@ -145,7 +145,7 @@ static const CGEN_OPINST sfmt_bl8_ops[] = {
static const CGEN_OPINST sfmt_bl24_ops[] = {
{ INPUT, "disp24", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP24), 0, 0 },
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
{ OUTPUT, "h_gr_SI_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ END }
};
@ -154,7 +154,7 @@ static const CGEN_OPINST sfmt_bcl8_ops[] = {
{ INPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
{ INPUT, "disp8", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP8), 0, COND_REF },
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
{ OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, COND_REF },
{ OUTPUT, "h_gr_SI_14", HW_H_GR, CGEN_MODE_SI, 0, 14, COND_REF },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
{ END }
};
@ -163,7 +163,7 @@ static const CGEN_OPINST sfmt_bcl24_ops[] = {
{ INPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
{ INPUT, "disp24", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP24), 0, COND_REF },
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
{ OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, COND_REF },
{ OUTPUT, "h_gr_SI_14", HW_H_GR, CGEN_MODE_SI, 0, 14, COND_REF },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
{ END }
};
@ -217,7 +217,7 @@ static const CGEN_OPINST sfmt_jc_ops[] = {
static const CGEN_OPINST sfmt_jl_ops[] = {
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
{ OUTPUT, "h_gr_SI_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ END }
};
@ -229,14 +229,44 @@ static const CGEN_OPINST sfmt_jmp_ops[] = {
};
static const CGEN_OPINST sfmt_ld_ops[] = {
{ INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "h_memory_SI_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_ld_d_ops[] = {
{ INPUT, "h_memory_add__DFLT_sr_slo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "h_memory_SI_add__DFLT_sr_slo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_ldb_ops[] = {
{ INPUT, "h_memory_QI_sr", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_ldb_d_ops[] = {
{ INPUT, "h_memory_QI_add__DFLT_sr_slo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
{ INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_ldh_ops[] = {
{ INPUT, "h_memory_HI_sr", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_ldh_d_ops[] = {
{ INPUT, "h_memory_HI_add__DFLT_sr_slo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
{ INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
@ -244,7 +274,7 @@ static const CGEN_OPINST sfmt_ld_d_ops[] = {
};
static const CGEN_OPINST sfmt_ld_plus_ops[] = {
{ INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "h_memory_SI_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ OUTPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
@ -270,10 +300,10 @@ static const CGEN_OPINST sfmt_ldi16_ops[] = {
};
static const CGEN_OPINST sfmt_lock_ops[] = {
{ INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "h_memory_SI_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
{ OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
{ OUTPUT, "h_lock", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
{ OUTPUT, "h_lock_BI", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
{ END }
};
@ -369,13 +399,13 @@ static const CGEN_OPINST sfmt_rac_dsi_ops[] = {
};
static const CGEN_OPINST sfmt_rte_ops[] = {
{ INPUT, "h_bbpsw", HW_H_BBPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_cr_14", HW_H_CR, CGEN_MODE_USI, 0, 14, 0 },
{ INPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ OUTPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ OUTPUT, "h_psw", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_bbpsw_UQI", HW_H_BBPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_bpsw_UQI", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_cr_USI_14", HW_H_CR, CGEN_MODE_USI, 0, 14, 0 },
{ INPUT, "h_cr_USI_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ OUTPUT, "h_bpsw_UQI", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_cr_USI_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ OUTPUT, "h_psw_UQI", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ END }
};
@ -403,7 +433,7 @@ static const CGEN_OPINST sfmt_slli_ops[] = {
static const CGEN_OPINST sfmt_st_ops[] = {
{ INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ OUTPUT, "h_memory_SI_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ END }
};
@ -411,14 +441,14 @@ static const CGEN_OPINST sfmt_st_d_ops[] = {
{ INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
{ INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_add__DFLT_src2_slo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ OUTPUT, "h_memory_SI_add__DFLT_src2_slo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_stb_ops[] = {
{ INPUT, "src1", HW_H_GR, CGEN_MODE_QI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
{ OUTPUT, "h_memory_QI_src2", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
{ END }
};
@ -426,14 +456,14 @@ static const CGEN_OPINST sfmt_stb_d_ops[] = {
{ INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
{ INPUT, "src1", HW_H_GR, CGEN_MODE_QI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_add__DFLT_src2_slo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
{ OUTPUT, "h_memory_QI_add__DFLT_src2_slo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_sth_ops[] = {
{ INPUT, "src1", HW_H_GR, CGEN_MODE_HI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
{ OUTPUT, "h_memory_HI_src2", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
{ END }
};
@ -441,39 +471,39 @@ static const CGEN_OPINST sfmt_sth_d_ops[] = {
{ INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
{ INPUT, "src1", HW_H_GR, CGEN_MODE_HI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_add__DFLT_src2_slo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
{ OUTPUT, "h_memory_HI_add__DFLT_src2_slo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_st_plus_ops[] = {
{ INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_memory_new_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ OUTPUT, "h_memory_SI_new_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
{ OUTPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_trap_ops[] = {
{ INPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ INPUT, "h_psw", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_bpsw_UQI", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "h_cr_USI_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ INPUT, "h_psw_UQI", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
{ INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
{ INPUT, "uimm4", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (UIMM4), 0, 0 },
{ OUTPUT, "h_bbpsw", HW_H_BBPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_cr_14", HW_H_CR, CGEN_MODE_USI, 0, 14, 0 },
{ OUTPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ OUTPUT, "h_psw", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_bbpsw_UQI", HW_H_BBPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_bpsw_UQI", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "h_cr_USI_14", HW_H_CR, CGEN_MODE_USI, 0, 14, 0 },
{ OUTPUT, "h_cr_USI_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
{ OUTPUT, "h_psw_UQI", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
{ OUTPUT, "pc", HW_H_PC, CGEN_MODE_SI, 0, 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_unlock_ops[] = {
{ INPUT, "h_lock", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
{ INPUT, "h_lock_BI", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
{ INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, COND_REF },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, COND_REF },
{ OUTPUT, "h_lock", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
{ OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, COND_REF },
{ OUTPUT, "h_lock_BI", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
{ OUTPUT, "h_memory_SI_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, COND_REF },
{ END }
};
@ -491,24 +521,24 @@ static const CGEN_OPINST sfmt_sat_ops[] = {
};
static const CGEN_OPINST sfmt_sadd_ops[] = {
{ INPUT, "h_accums_0", HW_H_ACCUMS, CGEN_MODE_DI, 0, 0, 0 },
{ INPUT, "h_accums_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ OUTPUT, "h_accums_0", HW_H_ACCUMS, CGEN_MODE_DI, 0, 0, 0 },
{ INPUT, "h_accums_DI_0", HW_H_ACCUMS, CGEN_MODE_DI, 0, 0, 0 },
{ INPUT, "h_accums_DI_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ OUTPUT, "h_accums_DI_0", HW_H_ACCUMS, CGEN_MODE_DI, 0, 0, 0 },
{ END }
};
static const CGEN_OPINST sfmt_macwu1_ops[] = {
{ INPUT, "h_accums_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ INPUT, "h_accums_DI_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_accums_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ OUTPUT, "h_accums_DI_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ END }
};
static const CGEN_OPINST sfmt_mulwu1_ops[] = {
{ INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
{ INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
{ OUTPUT, "h_accums_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ OUTPUT, "h_accums_DI_1", HW_H_ACCUMS, CGEN_MODE_DI, 0, 1, 0 },
{ END }
};
@ -576,14 +606,14 @@ static const CGEN_OPINST *m32r_cgen_opinst_table[MAX_INSNS] = {
& sfmt_jmp_ops[0],
& sfmt_ld_ops[0],
& sfmt_ld_d_ops[0],
& sfmt_ld_ops[0],
& sfmt_ld_d_ops[0],
& sfmt_ld_ops[0],
& sfmt_ld_d_ops[0],
& sfmt_ld_ops[0],
& sfmt_ld_d_ops[0],
& sfmt_ld_ops[0],
& sfmt_ld_d_ops[0],
& sfmt_ldb_ops[0],
& sfmt_ldb_d_ops[0],
& sfmt_ldh_ops[0],
& sfmt_ldh_d_ops[0],
& sfmt_ldb_ops[0],
& sfmt_ldb_d_ops[0],
& sfmt_ldh_ops[0],
& sfmt_ldh_d_ops[0],
& sfmt_ld_plus_ops[0],
& sfmt_ld24_ops[0],
& sfmt_ldi8_ops[0],

View File

@ -34,6 +34,7 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
#include "openrisc-desc.h"
#include "openrisc-opc.h"
#include "opintl.h"
#include "xregex.h"
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
@ -256,6 +257,104 @@ openrisc_cgen_init_asm (cd)
cd->parse_operand = openrisc_cgen_parse_operand;
}
/*
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 openrisc_cgen_assemble_insn
returns NULL for success, an error message for failure
*/
char *
openrisc_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.
@ -423,6 +522,7 @@ openrisc_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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))
@ -438,6 +538,7 @@ openrisc_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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 */
@ -454,6 +555,11 @@ openrisc_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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);
@ -481,6 +587,7 @@ openrisc_cgen_assemble_insn (cd, str, fields, buf, errmsg)
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)

View File

@ -129,9 +129,9 @@ static const CGEN_ISA openrisc_cgen_isa_table[] = {
/* Machine variants. */
static const CGEN_MACH openrisc_cgen_mach_table[] = {
{ "openrisc", "openrisc", MACH_OPENRISC },
{ "or1300", "openrisc:1300", MACH_OR1300 },
{ 0, 0, 0 }
{ "openrisc", "openrisc", MACH_OPENRISC, 0 },
{ "or1300", "openrisc:1300", MACH_OR1300, 0 },
{ 0, 0, 0, 0 }
};
static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
@ -177,7 +177,7 @@ CGEN_KEYWORD openrisc_cgen_opval_h_gr =
{
& openrisc_cgen_opval_h_gr_entries[0],
35,
0, 0, 0, 0
0, 0, 0, 0, ""
};
@ -779,11 +779,9 @@ static void
openrisc_cgen_rebuild_tables (cd)
CGEN_CPU_TABLE *cd;
{
int i,n_isas;
int i;
unsigned int isas = cd->isas;
#if 0
unsigned int machs = cd->machs;
#endif
cd->int_insn_p = CGEN_INT_INSN_P;
@ -821,20 +819,26 @@ openrisc_cgen_rebuild_tables (cd)
cd->min_insn_bitsize = isa->min_insn_bitsize;
if (isa->max_insn_bitsize > cd->max_insn_bitsize)
cd->max_insn_bitsize = isa->max_insn_bitsize;
++n_isas;
}
#if 0 /* Does nothing?? */
/* Data derived from the mach spec. */
for (i = 0; i < MAX_MACHS; ++i)
if (((1 << i) & machs) != 0)
{
const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
++n_machs;
if (mach->insn_chunk_bitsize != 0)
{
if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
{
fprintf (stderr, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
abort ();
}
cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
}
}
#endif
/* Determine which hw elements are used by MACH. */
build_hw_table (cd);

View File

@ -325,13 +325,19 @@ print_insn (cd, pc, info, buf, buflen)
char *buf;
int buflen;
{
unsigned long insn_value;
CGEN_INSN_INT insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
int rc = read_insn (cd, pc, info, buf, buflen, & ex_info, & insn_value);
if (rc != 0)
return rc;
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
insn_value = cgen_get_insn_value (cd, buf, buflen * 8);
/* Fill in ex_info fields like read_insn would. Don't actually call
read_insn, since the incoming buffer is already read (and possibly
modified a la m32r). */
ex_info.valid = (1 << buflen) - 1;
ex_info.dis_info = info;
ex_info.insn_bytes = buf;
/* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */
@ -342,6 +348,7 @@ print_insn (cd, pc, info, buf, buflen)
const CGEN_INSN *insn = insn_list->insn;
CGEN_FIELDS fields;
int length;
unsigned long insn_value_cropped;
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
/* not needed as insn shouldn't be in hash lists if not supported */
@ -356,7 +363,17 @@ print_insn (cd, pc, info, buf, buflen)
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
if ((insn_value & CGEN_INSN_BASE_MASK (insn))
/* Base size may exceed this instruction's size. Extract the
relevant part from the buffer. */
if ((CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
(CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
info->endian == BFD_ENDIAN_BIG);
else
insn_value_cropped = insn_value;
if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
@ -379,7 +396,7 @@ print_insn (cd, pc, info, buf, buflen)
}
else
length = CGEN_EXTRACT_FN (cd, insn)
(cd, insn, &ex_info, insn_value, &fields, pc);
(cd, insn, &ex_info, insn_value_cropped, &fields, pc);
/* length < 0 -> error */
if (length < 0)
@ -413,18 +430,27 @@ default_print_insn (cd, pc, info)
disassemble_info *info;
{
char buf[CGEN_MAX_INSN_SIZE];
int buflen;
int status;
/* Read the base part of the insn. */
/* Attempt to read the base part of the insn. */
buflen = cd->base_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
/* Try again with the minimum part, if min < base. */
if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
{
buflen = cd->min_insn_bitsize / 8;
status = (*info->read_memory_func) (pc, buf, buflen, info);
}
status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
return print_insn (cd, pc, info, buf, buflen);
}
/* Main entry point.

View File

@ -145,7 +145,22 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
}
/* Ensure VALUE will fit. */
if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
{
long minval = - (1L << (length - 1));
unsigned long maxval = mask;
if ((value > 0 && (unsigned long) value > maxval)
|| value < minval)
{
/* xgettext:c-format */
sprintf (errbuf,
_("operand out of range (%ld not between %ld and %lu)"),
value, minval, maxval);
return errbuf;
}
}
else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
{
unsigned long maxval = mask;
@ -400,7 +415,7 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
#endif
long *valuep;
{
CGEN_INSN_INT value, mask;
long value, mask;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
@ -428,9 +443,9 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
word_length = total_length;
}
/* Does the value reside in INSN_VALUE? */
/* Does the value reside in INSN_VALUE, and at the right alignment? */
if (CGEN_INT_INSN_P || word_offset == 0)
if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
{
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((word_offset + start + 1) - length);

View File

@ -678,6 +678,7 @@ openrisc_cgen_init_opcode_table (cd)
{
insns[i].base = &ib[i];
insns[i].opcode = &oc[i];
openrisc_cgen_build_insn_regex (& insns[i]);
}
cd->macro_insn_table.init_entries = insns;
cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
@ -686,7 +687,10 @@ openrisc_cgen_init_opcode_table (cd)
oc = & openrisc_cgen_insn_opcode_table[0];
insns = (CGEN_INSN *) cd->insn_table.init_entries;
for (i = 0; i < MAX_INSNS; ++i)
insns[i].opcode = &oc[i];
{
insns[i].opcode = &oc[i];
openrisc_cgen_build_insn_regex (& insns[i]);
}
cd->sizeof_fields = sizeof (CGEN_FIELDS);
cd->set_fields_bitsize = set_fields_bitsize;