* cgen-ibld.in (extract_normal): Match type of VALUE and MASK
to *VALUEP. Regenerate all cgen files.
This commit is contained in:
parent
d8b6305a45
commit
fc7bc88384
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue