Support for disassembling parallel instructions added.

Insn attributes hand patched until cgen can generate the correct values.
This commit is contained in:
Nick Clifton 1998-01-15 01:48:51 +00:00
parent cc662e8676
commit 23cf992f4a
6 changed files with 1610 additions and 1065 deletions

View File

@ -1,3 +1,16 @@
Wed Jan 14 17:37:03 1998 Nick Clifton <nickc@cygnus.com>
* m32r-dis.in: Generated file imported from cgen.
* cgen-asm.in: Formatting changes to improve readability.
* m32r-asm.c: Formatting changes to improve readability.
* cgen-dis.c: Formatting changes to improve readability.
* m32r-dis.c: Add support for disassembling parallel
instructions.
* m32r-opc.h: Update with latest version generated by cgen.
* m32r-opc.c: Update with latest version generated by cgen, plus
hand patches to allow attributes to work until cgen can generate
these correctly.
start-sanitize-r5900 start-sanitize-r5900
Tue Jan 13 09:21:56 1998 Jeffrey A Law (law@cygnus.com) Tue Jan 13 09:21:56 1998 Jeffrey A Law (law@cygnus.com)

View File

@ -21,6 +21,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "sysdep.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include "ansidecl.h" #include "ansidecl.h"
@ -34,10 +35,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
compiled with GCC), or switch to macros, or use something else. compiled with GCC), or switch to macros, or use something else.
*/ */
static const char *parse_insn_normal static const char * parse_insn_normal
PARAMS ((const struct cgen_insn *, const char **, struct cgen_fields *)); PARAMS ((const CGEN_INSN *, const char **, CGEN_FIELDS *));
static void insert_insn_normal static void insert_insn_normal
PARAMS ((const struct cgen_insn *, struct cgen_fields *, cgen_insn_t *)); PARAMS ((const CGEN_INSN *, CGEN_FIELDS *, cgen_insn_t *));
/* Default insertion routine. /* Default insertion routine.
@ -119,393 +120,6 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
} }
/* -- assembler routines inserted here */ /* -- assembler routines inserted here */
/* -- asm.c */
/* Handle shigh(), high(). */
static const char *
parse_h_hi16 (strp, opindex, min, max, valuep)
const char **strp;
int opindex;
unsigned long min, max;
unsigned long *valuep;
{
const char *errmsg;
/* FIXME: Need # in assembler syntax (means '#' is optional). */
if (**strp == '#')
++*strp;
if (strncmp (*strp, "high(", 5) == 0)
{
*strp += 5;
/* FIXME: If value was a number, right shift by 16. */
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_ULO, valuep);
if (**strp != ')')
return "missing `)'";
++*strp;
return errmsg;
}
else if (strncmp (*strp, "shigh(", 6) == 0)
{
*strp += 6;
/* FIXME: If value was a number, right shift by 16 (+ sign test). */
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_SLO, valuep);
if (**strp != ')')
return "missing `)'";
++*strp;
return errmsg;
}
return cgen_parse_unsigned_integer (strp, opindex, min, max, valuep);
}
/* Handle low() in a signed context. Also handle sda().
The signedness of the value doesn't matter to low(), but this also
handles the case where low() isn't present. */
static const char *
parse_h_slo16 (strp, opindex, min, max, valuep)
const char **strp;
int opindex;
long min, max;
long *valuep;
{
const char *errmsg;
/* FIXME: Need # in assembler syntax (means '#' is optional). */
if (**strp == '#')
++*strp;
if (strncmp (*strp, "low(", 4) == 0)
{
*strp += 4;
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16, valuep);
if (**strp != ')')
return "missing `)'";
++*strp;
return errmsg;
}
if (strncmp (*strp, "sda(", 4) == 0)
{
*strp += 4;
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_SDA16, valuep);
if (**strp != ')')
return "missing `)'";
++*strp;
return errmsg;
}
return cgen_parse_signed_integer (strp, opindex, min, max, valuep);
}
/* Handle low() in an unsigned context.
The signedness of the value doesn't matter to low(), but this also
handles the case where low() isn't present. */
static const char *
parse_h_ulo16 (strp, opindex, min, max, valuep)
const char **strp;
int opindex;
unsigned long min, max;
unsigned long *valuep;
{
const char *errmsg;
/* FIXME: Need # in assembler syntax (means '#' is optional). */
if (**strp == '#')
++*strp;
if (strncmp (*strp, "low(", 4) == 0)
{
*strp += 4;
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16, valuep);
if (**strp != ')')
return "missing `)'";
++*strp;
return errmsg;
}
return cgen_parse_unsigned_integer (strp, opindex, min, max, valuep);
}
/* -- */
/* Main entry point for operand parsing.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `parse_insn_normal', but keeping it
separate makes clear the interface between `parse_insn_normal' and each of
the handlers.
*/
CGEN_INLINE const char *
m32r_cgen_parse_operand (opindex, strp, fields)
int opindex;
const char **strp;
struct cgen_fields *fields;
{
const char *errmsg;
switch (opindex)
{
case 0 :
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r2);
break;
case 1 :
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r1);
break;
case 2 :
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r1);
break;
case 3 :
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r2);
break;
case 4 :
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, &fields->f_r2);
break;
case 5 :
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, &fields->f_r1);
break;
case 6 :
errmsg = cgen_parse_signed_integer (strp, 6, -128, 127, &fields->f_simm8);
break;
case 7 :
errmsg = cgen_parse_signed_integer (strp, 7, -32768, 32767, &fields->f_simm16);
break;
case 8 :
errmsg = cgen_parse_unsigned_integer (strp, 8, 0, 15, &fields->f_uimm4);
break;
case 9 :
errmsg = cgen_parse_unsigned_integer (strp, 9, 0, 31, &fields->f_uimm5);
break;
case 10 :
errmsg = cgen_parse_unsigned_integer (strp, 10, 0, 65535, &fields->f_uimm16);
break;
case 11 :
errmsg = parse_h_hi16 (strp, 11, 0, 65535, &fields->f_hi16);
break;
case 12 :
errmsg = parse_h_slo16 (strp, 12, -32768, 32767, &fields->f_simm16);
break;
case 13 :
errmsg = parse_h_ulo16 (strp, 13, 0, 65535, &fields->f_uimm16);
break;
case 14 :
errmsg = cgen_parse_address (strp, 14, 0, &fields->f_uimm24);
break;
case 15 :
errmsg = cgen_parse_address (strp, 15, 0, &fields->f_disp8);
break;
case 16 :
errmsg = cgen_parse_address (strp, 16, 0, &fields->f_disp16);
break;
case 17 :
errmsg = cgen_parse_address (strp, 17, 0, &fields->f_disp24);
break;
default :
fprintf (stderr, "Unrecognized field %d while parsing.\n", opindex);
abort ();
}
return errmsg;
}
/* Main entry point for operand insertion.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `parse_insn_normal', but keeping it
separate makes clear the interface between `parse_insn_normal' and each of
the handlers. It's also needed by GAS to insert operands that couldn't be
resolved during parsing.
*/
CGEN_INLINE void
m32r_cgen_insert_operand (opindex, fields, buffer)
int opindex;
struct cgen_fields *fields;
cgen_insn_t *buffer;
{
switch (opindex)
{
case 0 :
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 1 :
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 2 :
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 3 :
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 4 :
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 5 :
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 6 :
insert_normal (fields->f_simm8, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 7 :
insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 8 :
insert_normal (fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 9 :
insert_normal (fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 10 :
insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 11 :
insert_normal (fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 12 :
insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 13 :
insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 14 :
insert_normal (fields->f_uimm24, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 15 :
insert_normal (fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 16 :
insert_normal (fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case 17 :
insert_normal (fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
default :
fprintf (stderr, "Unrecognized field %d while building insn.\n",
opindex);
abort ();
}
}
/* Main entry point for operand validation.
This function is called from GAS when it has fully resolved an operand
that couldn't be resolved during parsing.
The result is NULL for success or an error message (which may be
computed into a static buffer).
*/
CGEN_INLINE const char *
m32r_cgen_validate_operand (opindex, fields)
int opindex;
const struct cgen_fields *fields;
{
const char *errmsg = NULL;
switch (opindex)
{
case 0 :
/* nothing to do */
break;
case 1 :
/* nothing to do */
break;
case 2 :
/* nothing to do */
break;
case 3 :
/* nothing to do */
break;
case 4 :
/* nothing to do */
break;
case 5 :
/* nothing to do */
break;
case 6 :
errmsg = cgen_validate_signed_integer (fields->f_simm8, -128, 127);
break;
case 7 :
errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
break;
case 8 :
errmsg = cgen_validate_unsigned_integer (fields->f_uimm4, 0, 15);
break;
case 9 :
errmsg = cgen_validate_unsigned_integer (fields->f_uimm5, 0, 31);
break;
case 10 :
errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
break;
case 11 :
errmsg = cgen_validate_unsigned_integer (fields->f_hi16, 0, 65535);
break;
case 12 :
errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
break;
case 13 :
errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
break;
case 14 :
/* nothing to do */
break;
case 15 :
/* nothing to do */
break;
case 16 :
/* nothing to do */
break;
case 17 :
/* nothing to do */
break;
default :
fprintf (stderr, "Unrecognized field %d while validating operand.\n",
opindex);
abort ();
}
return errmsg;
}
cgen_parse_fn *m32r_cgen_parse_handlers[] = {
0, /* default */
parse_insn_normal,
};
cgen_insert_fn *m32r_cgen_insert_handlers[] = {
0, /* default */
insert_insn_normal,
};
void
m32r_cgen_init_asm (mach, endian)
int mach;
enum cgen_endian endian;
{
m32r_cgen_init_tables (mach);
cgen_set_cpu (& m32r_cgen_opcode_data, mach, endian);
cgen_asm_init ();
}
/* Default insn parser. /* Default insn parser.
@ -523,32 +137,26 @@ m32r_cgen_init_asm (mach, endian)
static const char * static const char *
parse_insn_normal (insn, strp, fields) parse_insn_normal (insn, strp, fields)
const struct cgen_insn *insn; const CGEN_INSN *insn;
const char **strp; const char **strp;
struct cgen_fields *fields; CGEN_FIELDS *fields;
{ {
const struct cgen_syntax *syntax = CGEN_INSN_SYNTAX (insn); const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
const char *str = *strp; const char *str = *strp;
const char *errmsg; const char *errmsg;
const char *p;
const unsigned char *syn; const unsigned char *syn;
#ifdef CGEN_MNEMONIC_OPERANDS #ifdef CGEN_MNEMONIC_OPERANDS
int past_opcode_p; int past_opcode_p;
#endif #endif
/* If mnemonics are constant, they're not stored with the syntax string. */ /* For now we assume the mnemonic is first (there are no leading operands).
#ifndef CGEN_MNEMONIC_OPERANDS We can parse it without needing to set up operand parsing. */
{ p = CGEN_INSN_MNEMONIC (insn);
const char *p = syntax->mnemonic; while (*p && *p == *str)
++p, ++str;
while (*p && *p == *str) if (*p || (*str && !isspace (*str)))
++p, ++str; return "unrecognized instruction";
if (*p || (*str && !isspace (*str)))
return "unrecognized instruction";
while (isspace (*str))
++str;
}
#endif
CGEN_INIT_PARSE (); CGEN_INIT_PARSE ();
cgen_init_parse_operand (); cgen_init_parse_operand ();
@ -558,7 +166,12 @@ parse_insn_normal (insn, strp, fields)
/* We don't check for (*str != '\0') here because we want to parse /* We don't check for (*str != '\0') here because we want to parse
any trailing fake arguments in the syntax string. */ any trailing fake arguments in the syntax string. */
for (syn = syntax->syntax; *syn != '\0'; ) syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
/* Mnemonics come first for now, ensure valid string. */
if (! CGEN_SYNTAX_MNEMONIC_P (*syn))
abort ();
++syn;
while (*syn != 0)
{ {
/* Non operand chars must match exactly. */ /* Non operand chars must match exactly. */
/* FIXME: Need to better handle whitespace. */ /* FIXME: Need to better handle whitespace. */
@ -617,16 +230,16 @@ parse_insn_normal (insn, strp, fields)
static void static void
insert_insn_normal (insn, fields, buffer) insert_insn_normal (insn, fields, buffer)
const struct cgen_insn *insn; const CGEN_INSN *insn;
struct cgen_fields *fields; CGEN_FIELDS *fields;
cgen_insn_t *buffer; cgen_insn_t *buffer;
{ {
const struct cgen_syntax *syntax = CGEN_INSN_SYNTAX (insn); const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
bfd_vma value; bfd_vma value;
const unsigned char *syn; const unsigned char *syn;
CGEN_INIT_INSERT (); CGEN_INIT_INSERT ();
value = syntax->value; value = CGEN_INSN_VALUE (insn);
/* If we're recording insns as numbers (rather than a string of bytes), /* If we're recording insns as numbers (rather than a string of bytes),
target byte order handling is deferred until later. */ target byte order handling is deferred until later. */
@ -660,7 +273,7 @@ insert_insn_normal (insn, fields, buffer)
/* ??? Rather than scanning the syntax string again, we could store /* ??? Rather than scanning the syntax string again, we could store
in `fields' a null terminated list of the fields that are present. */ in `fields' a null terminated list of the fields that are present. */
for (syn = syntax->syntax; *syn != '\0'; ++syn) for (syn = CGEN_SYNTAX_STRING (syntax); *syn != '\0'; ++syn)
{ {
if (CGEN_SYNTAX_CHAR_P (*syn)) if (CGEN_SYNTAX_CHAR_P (*syn))
continue; continue;
@ -677,10 +290,10 @@ insert_insn_normal (insn, fields, buffer)
or NULL if an error occured (an error message will have already been or NULL if an error occured (an error message will have already been
printed). */ printed). */
const struct cgen_insn * const CGEN_INSN *
m32r_cgen_assemble_insn (str, fields, buf, errmsg) m32r_cgen_assemble_insn (str, fields, buf, errmsg)
const char *str; const char *str;
struct cgen_fields *fields; CGEN_FIELDS *fields;
cgen_insn_t *buf; cgen_insn_t *buf;
char **errmsg; char **errmsg;
{ {
@ -700,7 +313,7 @@ m32r_cgen_assemble_insn (str, fields, buf, errmsg)
start = str; start = str;
for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
{ {
const struct cgen_insn *insn = ilist->insn; const CGEN_INSN *insn = ilist->insn;
#if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */ #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
/* Is this insn supported by the selected cpu? */ /* Is this insn supported by the selected cpu? */
@ -758,12 +371,15 @@ m32r_cgen_assemble_insn (str, fields, buf, errmsg)
This lets GAS parse registers for us. This lets GAS parse registers for us.
??? Interesting idea but not currently used. */ ??? Interesting idea but not currently used. */
/* Record each member of OPVALS in the assembler's symbol table.
FIXME: Not currently used. */
void void
m32r_cgen_asm_hash_keywords (opvals) m32r_cgen_asm_hash_keywords (opvals)
struct cgen_keyword *opvals; CGEN_KEYWORD *opvals;
{ {
struct cgen_keyword_search search = cgen_keyword_search_init (opvals, NULL); CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
const struct cgen_keyword_entry *ke; const CGEN_KEYWORD_ENTRY *ke;
while ((ke = cgen_keyword_search_next (&search)) != NULL) while ((ke = cgen_keyword_search_next (&search)) != NULL)
{ {

View File

@ -21,11 +21,12 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "sysdep.h"
#include <stdio.h> #include <stdio.h>
#include "ansidecl.h" #include "ansidecl.h"
#include "dis-asm.h" #include "dis-asm.h"
#include "m32r-opc.h"
#include "bfd.h" #include "bfd.h"
#include "m32r-opc.h"
/* ??? The layout of this stuff is still work in progress. /* ??? The layout of this stuff is still work in progress.
For speed in assembly/disassembly, we use inline functions. That of course For speed in assembly/disassembly, we use inline functions. That of course
@ -45,9 +46,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static int print_insn PARAMS ((bfd_vma, disassemble_info *, char *, int)); static int print_insn PARAMS ((bfd_vma, disassemble_info *, char *, int));
static int extract_insn_normal static int extract_insn_normal
PARAMS ((const struct cgen_insn *, void *, cgen_insn_t, struct cgen_fields *)); PARAMS ((const CGEN_INSN *, void *, cgen_insn_t, CGEN_FIELDS *));
static void print_insn_normal static void print_insn_normal
PARAMS ((void *, const struct cgen_insn *, struct cgen_fields *, bfd_vma, int)); PARAMS ((void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int));
CGEN_INLINE void
m32r_cgen_print_operand
PARAMS ((int opindex, disassemble_info * info, CGEN_FIELDS * fields, void const * attrs, bfd_vma pc, int length));
/* Default extraction routine. /* Default extraction routine.
@ -56,11 +62,14 @@ static void print_insn_normal
static int static int
extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length, valuep) extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length, valuep)
void *buf_ctrl; void * buf_ctrl;
cgen_insn_t insn_value; cgen_insn_t insn_value;
unsigned int attrs; unsigned int attrs;
int start, length, shift, total_length; int start;
long *valuep; int length;
int shift;
int total_length;
long * valuep;
{ {
long value; long value;
@ -85,7 +94,7 @@ extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length,
else else
value <<= shift; value <<= shift;
*valuep = value; * valuep = value;
return 1; return 1;
} }
@ -93,13 +102,13 @@ extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length,
static void static void
print_normal (dis_info, value, attrs, pc, length) print_normal (dis_info, value, attrs, pc, length)
void *dis_info; void * dis_info;
long value; long value;
unsigned int attrs; unsigned int attrs;
unsigned long pc; /* FIXME: should be bfd_vma */ unsigned long pc; /* FIXME: should be bfd_vma */
int length; int length;
{ {
disassemble_info *info = dis_info; disassemble_info * info = dis_info;
/* Print the operand as directed by the attributes. */ /* Print the operand as directed by the attributes. */
if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_FAKE)) if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_FAKE))
@ -120,264 +129,19 @@ print_normal (dis_info, value, attrs, pc, length)
static void static void
print_keyword (dis_info, keyword_table, value, attrs) print_keyword (dis_info, keyword_table, value, attrs)
void *dis_info; void * dis_info;
struct cgen_keyword *keyword_table; CGEN_KEYWORD * keyword_table;
long value; long value;
CGEN_ATTR *attrs; CGEN_ATTR * attrs;
{ {
disassemble_info *info = dis_info; disassemble_info * info = dis_info;
const struct cgen_keyword_entry *ke; const CGEN_KEYWORD_ENTRY * ke;
ke = cgen_keyword_lookup_value (keyword_table, value); ke = cgen_keyword_lookup_value (keyword_table, value);
if (ke != NULL) info->fprintf_func (info->stream, "%s", ke == NULL ? "???" : ke->name);
(*info->fprintf_func) (info->stream, "%s", ke->name);
else
(*info->fprintf_func) (info->stream, "???");
} }
/* -- disassembler routines inserted here */ /* -- disassembler routines inserted here */
/* -- dis.c */
#undef CGEN_PRINT_INSN
#define CGEN_PRINT_INSN my_print_insn
static int
my_print_insn (pc, info, buf, buflen)
bfd_vma pc;
disassemble_info *info;
char *buf;
int buflen;
{
unsigned long insn_value;
/* 32 bit insn? */
if ((pc & 3) == 0 && (buf[0] & 0x80) != 0)
return print_insn (pc, info, buf, buflen);
/* Print the first insn. */
if ((pc & 3) == 0)
{
if (print_insn (pc, info, buf, 16) == 0)
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
buf += 2;
}
if (buf[0] & 0x80)
{
/* Parallel. */
(*info->fprintf_func) (info->stream, " || ");
buf[0] &= 0x7f;
}
else
(*info->fprintf_func) (info->stream, " -> ");
/* The "& 3" is to ensure the branch address is computed correctly
[if it is a branch]. */
if (print_insn (pc & ~ (bfd_vma) 3, info, buf, 16) == 0)
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
return (pc & 3) ? 2 : 4;
}
/* -- */
/* Main entry point for operand extraction.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers.
*/
CGEN_INLINE int
m32r_cgen_extract_operand (opindex, buf_ctrl, insn_value, fields)
int opindex;
void *buf_ctrl;
cgen_insn_t insn_value;
struct cgen_fields *fields;
{
int length;
switch (opindex)
{
case 0 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r2);
break;
case 1 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r1);
break;
case 2 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r1);
break;
case 3 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r2);
break;
case 4 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r2);
break;
case 5 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r1);
break;
case 6 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm8);
break;
case 7 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm16);
break;
case 8 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm4);
break;
case 9 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm5);
break;
case 10 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm16);
break;
case 11 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_hi16);
break;
case 12 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm16);
break;
case 13 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm16);
break;
case 14 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm24);
break;
case 15 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, 2, CGEN_FIELDS_BITSIZE (fields), &fields->f_disp8);
break;
case 16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, 2, CGEN_FIELDS_BITSIZE (fields), &fields->f_disp16);
break;
case 17 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, 2, CGEN_FIELDS_BITSIZE (fields), &fields->f_disp24);
break;
default :
fprintf (stderr, "Unrecognized field %d while decoding insn.\n",
opindex);
abort ();
}
return length;
}
/* Main entry point for printing operands.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers.
*/
CGEN_INLINE void
m32r_cgen_print_operand (opindex, info, fields, attrs, pc, length)
int opindex;
disassemble_info *info;
struct cgen_fields *fields;
int attrs;
bfd_vma pc;
int length;
{
switch (opindex)
{
case 0 :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case 1 :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case 2 :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case 3 :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case 4 :
print_keyword (info, & m32r_cgen_opval_h_cr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case 5 :
print_keyword (info, & m32r_cgen_opval_h_cr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case 6 :
print_normal (info, fields->f_simm8, 0, pc, length);
break;
case 7 :
print_normal (info, fields->f_simm16, 0, pc, length);
break;
case 8 :
print_normal (info, fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case 9 :
print_normal (info, fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case 10 :
print_normal (info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case 11 :
print_normal (info, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case 12 :
print_normal (info, fields->f_simm16, 0, pc, length);
break;
case 13 :
print_normal (info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case 14 :
print_normal (info, fields->f_uimm24, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case 15 :
print_normal (info, fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case 16 :
print_normal (info, fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case 17 :
print_normal (info, fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
default :
fprintf (stderr, "Unrecognized field %d while printing insn.\n",
opindex);
abort ();
}
}
cgen_extract_fn *m32r_cgen_extract_handlers[] = {
0, /* default */
extract_insn_normal,
};
cgen_print_fn *m32r_cgen_print_handlers[] = {
0, /* default */
print_insn_normal,
};
void
m32r_cgen_init_dis (mach, endian)
int mach;
enum cgen_endian endian;
{
m32r_cgen_init_tables (mach);
cgen_set_cpu (& m32r_cgen_opcode_data, mach, endian);
cgen_dis_init ();
}
/* Default insn extractor. /* Default insn extractor.
@ -387,42 +151,33 @@ m32r_cgen_init_dis (mach, endian)
static int static int
extract_insn_normal (insn, buf_ctrl, insn_value, fields) extract_insn_normal (insn, buf_ctrl, insn_value, fields)
const struct cgen_insn *insn; const CGEN_INSN * insn;
void *buf_ctrl; void * buf_ctrl;
cgen_insn_t insn_value; cgen_insn_t insn_value;
struct cgen_fields *fields; CGEN_FIELDS * fields;
{ {
const struct cgen_syntax *syntax = CGEN_INSN_SYNTAX (insn); const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
const unsigned char *syn; const unsigned char * syn;
/* ??? Some of the operand extract routines need to know the insn length,
which might be computed as we go. Set a default value and it'll be
modified as necessary. */
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
CGEN_INIT_EXTRACT (); CGEN_INIT_EXTRACT ();
for (syn = syntax->syntax; *syn; ++syn) for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
{ {
int length; int length;
if (CGEN_SYNTAX_CHAR_P (*syn)) if (CGEN_SYNTAX_CHAR_P (* syn))
continue; continue;
length = m32r_cgen_extract_operand (CGEN_SYNTAX_FIELD (*syn), length = m32r_cgen_extract_operand (CGEN_SYNTAX_FIELD (* syn),
buf_ctrl, insn_value, fields); buf_ctrl, insn_value, fields);
if (length == 0) if (length == 0)
return 0; return 0;
} }
/* We recognized and successfully extracted this insn. /* We recognized and successfully extracted this insn. */
If a length is recorded with this insn, it has a fixed length. return CGEN_INSN_BITSIZE (insn);
Otherwise we require the syntax string to have a fake operand which
sets the `length' field in `flds'. */
/* FIXME: wip */
if (syntax->length > 0)
return syntax->length;
return fields->length;
} }
/* Default insn printer. /* Default insn printer.
@ -433,28 +188,33 @@ extract_insn_normal (insn, buf_ctrl, insn_value, fields)
static void static void
print_insn_normal (dis_info, insn, fields, pc, length) print_insn_normal (dis_info, insn, fields, pc, length)
void *dis_info; void * dis_info;
const struct cgen_insn *insn; const CGEN_INSN * insn;
struct cgen_fields *fields; CGEN_FIELDS * fields;
bfd_vma pc; bfd_vma pc;
int length; int length;
{ {
const struct cgen_syntax *syntax = CGEN_INSN_SYNTAX (insn); const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
disassemble_info *info = dis_info; disassemble_info * info = dis_info;
const unsigned char *syn; const unsigned char * syn;
CGEN_INIT_PRINT (); CGEN_INIT_PRINT ();
for (syn = syntax->syntax; *syn; ++syn) for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
{ {
if (CGEN_SYNTAX_CHAR_P (*syn)) if (CGEN_SYNTAX_MNEMONIC_P (* syn))
{ {
(*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn)); info->fprintf_func (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
continue;
}
if (CGEN_SYNTAX_CHAR_P (* syn))
{
info->fprintf_func (info->stream, "%c", CGEN_SYNTAX_CHAR (* syn));
continue; continue;
} }
/* We have an operand. */ /* We have an operand. */
m32r_cgen_print_operand (CGEN_SYNTAX_FIELD (*syn), info, m32r_cgen_print_operand (CGEN_SYNTAX_FIELD (* syn), info,
fields, CGEN_INSN_ATTRS (insn), pc, length); fields, CGEN_INSN_ATTRS (insn), pc, length);
} }
} }
@ -471,15 +231,16 @@ print_insn_normal (dis_info, insn, fields, pc, length)
static int static int
print_insn (pc, info, buf, buflen) print_insn (pc, info, buf, buflen)
bfd_vma pc; bfd_vma pc;
disassemble_info *info; disassemble_info * info;
char *buf; char * buf;
int buflen; int buflen;
{ {
int i; int i;
unsigned long insn_value; unsigned long insn_value;
const CGEN_INSN_LIST *insn_list; const CGEN_INSN_LIST * insn_list;
int extra_bytes;
switch (buflen) switch (buflen)
{ {
case 8: case 8:
@ -495,16 +256,52 @@ print_insn (pc, info, buf, buflen)
abort (); abort ();
} }
/* Special case - a 32 bit instruction which is actually two 16 bit instructions
being executed in parallel. */
if (buflen == 32
&& ((insn_value & 0x80008000) == 0x00008000))
{
if (info->endian == BFD_ENDIAN_BIG)
{
static char buf2 [4];
print_insn (pc, info, buf, 16);
info->fprintf_func (info->stream, " || ");
buf2 [0] = buf [2] & ~ 0x80;
buf2 [1] = buf [3];
buf2 [2] = 0;
buf2 [3] = 0;
buf = buf2;
insn_value <<= 17;
insn_value >>= 1;
}
else
{
print_insn (pc, info, buf + 2, 16);
info->fprintf_func (info->stream, " || ");
insn_value &= 0x7fff;
}
pc += 2;
extra_bytes = 2;
}
else
extra_bytes = 0;
/* The instructions are stored in hash lists. /* The instructions are stored in hash lists.
Pick the first one and keep trying until we find the right one. */ Pick the first one and keep trying until we find the right one. */
insn_list = CGEN_DIS_LOOKUP_INSN (buf, insn_value); insn_list = CGEN_DIS_LOOKUP_INSN (buf, insn_value);
while (insn_list != NULL) while (insn_list != NULL)
{ {
const CGEN_INSN *insn = insn_list->insn; const CGEN_INSN * insn = insn_list->insn;
const struct cgen_syntax *syntax = CGEN_INSN_SYNTAX (insn); unsigned long value;
struct cgen_fields fields;
int length;
#if 0 /* not needed as insn shouldn't be in hash lists if not supported */ #if 0 /* not needed as insn shouldn't be in hash lists if not supported */
/* Supported by this cpu? */ /* Supported by this cpu? */
@ -512,28 +309,43 @@ print_insn (pc, info, buf, buflen)
continue; continue;
#endif #endif
/* If we are looking at a 16 bit insn we may have to adjust the value being examined. */
value = insn_value;
if (CGEN_INSN_BITSIZE (insn) == 16)
{
/* If this is a big endian target,
and we have read 32 bits for the instruction value,
then we must examine the top 16 bits, not the bottom. */
if (buflen == 32 && info->endian == BFD_ENDIAN_BIG)
value >>= 16;
}
/* Basic bit mask must be correct. */ /* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract /* ??? May wish to allow target to defer this check until the extract
handler. */ handler. */
if ((insn_value & syntax->mask) == syntax->value) if ((value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
{ {
CGEN_FIELDS fields;
int length;
/* Printing is handled in two passes. The first pass parses the /* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints machine insn and extracts the fields. The second pass prints
them. */ them. */
length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields); length = CGEN_EXTRACT_FN (insn) (insn, NULL, value, & fields);
if (length > 0) if (length > 0)
{ {
(*CGEN_PRINT_FN (insn)) (info, insn, &fields, pc, length); CGEN_PRINT_FN (insn) (info, insn, & fields, pc, length);
/* length is in bits, result is in bytes */ /* length is in bits, result is in bytes */
return length / 8; return (length / 8) + extra_bytes;
} }
} }
insn_list = CGEN_DIS_NEXT_INSN (insn_list); insn_list = CGEN_DIS_NEXT_INSN (insn_list);
} }
return 0; return extra_bytes;
} }
/* Main entry point. /* Main entry point.
@ -542,44 +354,58 @@ print_insn (pc, info, buf, buflen)
int int
print_insn_m32r (pc, info) print_insn_m32r (pc, info)
bfd_vma pc; bfd_vma pc;
disassemble_info *info; disassemble_info * info;
{ {
char buffer[CGEN_MAX_INSN_SIZE]; char buffer [CGEN_MAX_INSN_SIZE];
int status, length; int status;
static int initialized = 0; int length;
static int current_mach = 0; static int initialized = 0;
static int current_big_p = 0; static int current_mach = 0;
int mach = info->mach; static int current_bigend = 0;
int big_p = info->endian == BFD_ENDIAN_BIG; int mach = info->mach;
int bigend = info->endian == BFD_ENDIAN_BIG;
/* If we haven't initialized yet, or if we've switched cpu's, initialize. */ /* If we haven't initialized yet, or if we've switched cpu's, initialize. */
if (!initialized || mach != current_mach || big_p != current_big_p) if (!initialized || mach != current_mach || bigend != current_bigend)
{ {
initialized = 1; initialized = 1;
current_mach = mach; current_mach = mach;
current_big_p = big_p; current_bigend = bigend;
m32r_cgen_init_dis (mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
m32r_cgen_init_dis (mach, bigend ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
} }
/* Read enough of the insn so we can look it up in the hash lists. */ /* Read enough of the insn so we can look it up in the hash lists. */
status = (*info->read_memory_func) (pc, buffer, CGEN_BASE_INSN_SIZE, info); status = info->read_memory_func (pc, buffer, CGEN_BASE_INSN_SIZE, info);
if (status != 0) if (status != 0)
{ {
(*info->memory_error_func) (status, pc, info); /* Try reading a 16 bit instruction. */
info->bytes_per_chunk = 2;
status = info->read_memory_func (pc, buffer, CGEN_BASE_INSN_SIZE / 2, info);
buffer [2] = buffer [3] = 0;
}
if (status != 0)
{
info->memory_error_func (status, pc, info);
return -1; return -1;
} }
/* We try to have as much common code as possible. /* We try to have as much common code as possible.
But at this point some targets need to take over. */ But at this point some targets need to take over. */
/* ??? Some targets may need a hook elsewhere. Try to avoid this, /* ??? Some targets may need a hook elsewhere. Try to avoid this,
but if not possible, try to move this hook elsewhere rather than but if not possible try to move this hook elsewhere rather than
have two hooks. */ have two hooks. */
length = CGEN_PRINT_INSN (pc, info, buffer, CGEN_BASE_INSN_BITSIZE); length = CGEN_PRINT_INSN (pc, info, buffer, CGEN_BASE_INSN_BITSIZE);
if (length) if (length)
return length; return length;
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); info->fprintf_func (info->stream, UNKNOWN_INSN_MSG);
return CGEN_DEFAULT_INSN_SIZE; return CGEN_DEFAULT_INSN_SIZE;
} }
/* Get the generate machine specific code. */
#include "m32r-dis.in"

252
opcodes/m32r-dis.in Normal file
View File

@ -0,0 +1,252 @@
/* -- dis.c */
#undef CGEN_PRINT_INSN
#define CGEN_PRINT_INSN my_print_insn
static int
my_print_insn (pc, info, buf, buflen)
bfd_vma pc;
disassemble_info *info;
char *buf;
int buflen;
{
/* 32 bit insn? */
if ((pc & 3) == 0 && (buf[0] & 0x80) != 0)
return print_insn (pc, info, buf, buflen);
/* Print the first insn. */
if ((pc & 3) == 0)
{
if (print_insn (pc, info, buf, 16) == 0)
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
buf += 2;
}
if (buf[0] & 0x80)
{
/* Parallel. */
(*info->fprintf_func) (info->stream, " || ");
buf[0] &= 0x7f;
}
else
(*info->fprintf_func) (info->stream, " -> ");
/* The "& 3" is to ensure the branch address is computed correctly
[if it is a branch]. */
if (print_insn (pc & ~ (bfd_vma) 3, info, buf, 16) == 0)
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
return (pc & 3) ? 2 : 4;
}
/* -- */
/* Main entry point for operand extraction.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers.
*/
CGEN_INLINE int
m32r_cgen_extract_operand (opindex, buf_ctrl, insn_value, fields)
int opindex;
void *buf_ctrl;
cgen_insn_t insn_value;
CGEN_FIELDS *fields;
{
int length;
switch (opindex)
{
case M32R_OPERAND_SR :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r2);
break;
case M32R_OPERAND_DR :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r1);
break;
case M32R_OPERAND_SRC1 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r1);
break;
case M32R_OPERAND_SRC2 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r2);
break;
case M32R_OPERAND_SCR :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r2);
break;
case M32R_OPERAND_DCR :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_r1);
break;
case M32R_OPERAND_SIMM8 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm8);
break;
case M32R_OPERAND_SIMM16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm16);
break;
case M32R_OPERAND_UIMM4 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm4);
break;
case M32R_OPERAND_UIMM5 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm5);
break;
case M32R_OPERAND_UIMM16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm16);
break;
case M32R_OPERAND_ACC_S :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_acc_s);
break;
case M32R_OPERAND_ACC :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_acc);
break;
case M32R_OPERAND_HI16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_hi16);
break;
case M32R_OPERAND_SLO16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm16);
break;
case M32R_OPERAND_ULO16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm16);
break;
case M32R_OPERAND_UIMM24 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_uimm24);
break;
case M32R_OPERAND_DISP8 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, 2, CGEN_FIELDS_BITSIZE (fields), &fields->f_disp8);
break;
case M32R_OPERAND_DISP16 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, 2, CGEN_FIELDS_BITSIZE (fields), &fields->f_disp16);
break;
case M32R_OPERAND_DISP24 :
length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, 2, CGEN_FIELDS_BITSIZE (fields), &fields->f_disp24);
break;
default :
fprintf (stderr, "Unrecognized field %d while decoding insn.\n",
opindex);
abort ();
}
return length;
}
/* Main entry point for printing operands.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers.
*/
CGEN_INLINE void
m32r_cgen_print_operand (opindex, info, fields, attrs, pc, length)
int opindex;
disassemble_info *info;
CGEN_FIELDS *fields;
void const * attrs;
bfd_vma pc;
int length;
{
switch (opindex)
{
case M32R_OPERAND_SR :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_DR :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_SRC1 :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_SRC2 :
print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_SCR :
print_keyword (info, & m32r_cgen_opval_h_cr, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_DCR :
print_keyword (info, & m32r_cgen_opval_h_cr, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_SIMM8 :
print_normal (info, fields->f_simm8, 0, pc, length);
break;
case M32R_OPERAND_SIMM16 :
print_normal (info, fields->f_simm16, 0, pc, length);
break;
case M32R_OPERAND_UIMM4 :
print_normal (info, fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case M32R_OPERAND_UIMM5 :
print_normal (info, fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case M32R_OPERAND_UIMM16 :
print_normal (info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case M32R_OPERAND_ACC_S :
print_keyword (info, & m32r_cgen_opval_h_accums, fields->f_acc_s, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_ACC :
print_keyword (info, & m32r_cgen_opval_h_accums, fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case M32R_OPERAND_HI16 :
print_normal (info, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case M32R_OPERAND_SLO16 :
print_normal (info, fields->f_simm16, 0, pc, length);
break;
case M32R_OPERAND_ULO16 :
print_normal (info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case M32R_OPERAND_UIMM24 :
print_normal (info, fields->f_uimm24, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case M32R_OPERAND_DISP8 :
print_normal (info, fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case M32R_OPERAND_DISP16 :
print_normal (info, fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case M32R_OPERAND_DISP24 :
print_normal (info, fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
default :
fprintf (stderr, "Unrecognized field %d while printing insn.\n",
opindex);
abort ();
}
}
cgen_extract_fn *m32r_cgen_extract_handlers[] = {
0, /* default */
extract_insn_normal,
};
cgen_print_fn *m32r_cgen_print_handlers[] = {
0, /* default */
print_insn_normal,
};
void
m32r_cgen_init_dis (mach, endian)
int mach;
enum cgen_endian endian;
{
m32r_cgen_init_tables (mach);
cgen_set_cpu (& m32r_cgen_opcode_data, mach, endian);
cgen_dis_init ();
}

File diff suppressed because it is too large Load Diff

234
opcodes/m32r-opc.h Normal file
View File

@ -0,0 +1,234 @@
/* Instruction description for m32r.
This file is machine generated.
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU Binutils and/or GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef m32r_OPC_H
#define m32r_OPC_H
#define CGEN_ARCH m32r
/* Given symbol S, return m32r_cgen_<s>. */
#define CGEN_SYM(s) CGEN_CAT3 (m32r,_cgen_,s)
#define CGEN_WORD_BITSIZE 32
#define CGEN_DEFAULT_INSN_BITSIZE 32
#define CGEN_BASE_INSN_BITSIZE 32
#define CGEN_MAX_INSN_BITSIZE 32
#define CGEN_DEFAULT_INSN_SIZE (CGEN_DEFAULT_INSN_BITSIZE / 8)
#define CGEN_BASE_INSN_SIZE (CGEN_BASE_INSN_BITSIZE / 8)
#define CGEN_MAX_INSN_SIZE (CGEN_MAX_INSN_BITSIZE / 8)
#define CGEN_INT_INSN
/* +1 because the first entry is reserved (null) */
#define CGEN_NUM_INSNS (165 + 1)
#define CGEN_NUM_OPERANDS (24)
/* Number of non-boolean attributes. */
#define CGEN_MAX_INSN_ATTRS 2
#define CGEN_MAX_OPERAND_ATTRS 0
/* FIXME: Need to compute CGEN_MAX_SYNTAX_BYTES. */
/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands.
e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands
we can't hash on everything up to the space. */
#define CGEN_MNEMONIC_OPERANDS
/* Number of architecture variants. */
#define MAX_MACHS 2
/* Enums. */
/* Enum declaration for insn format enums. */
typedef enum insn_op1 {
OP1_0 = 0, OP1_1 = 1, OP1_2 = 2, OP1_3 = 3,
OP1_4 = 4, OP1_5 = 5, OP1_6 = 6, OP1_7 = 7,
OP1_8 = 8, OP1_9 = 9, OP1_10 = 10, OP1_11 = 11,
OP1_12 = 12, OP1_13 = 13, OP1_14 = 14, OP1_15 = 15
} INSN_OP1;
/* Enum declaration for op2 enums. */
typedef enum insn_op2 {
OP2_0 = 0, OP2_1 = 1, OP2_2 = 2, OP2_3 = 3,
OP2_4 = 4, OP2_5 = 5, OP2_6 = 6, OP2_7 = 7,
OP2_8 = 8, OP2_9 = 9, OP2_10 = 10, OP2_11 = 11,
OP2_12 = 12, OP2_13 = 13, OP2_14 = 14, OP2_15 = 15
} INSN_OP2;
/* Enum declaration for m32r operand types. */
typedef enum cgen_operand_type {
M32R_OPERAND_PC = 0, M32R_OPERAND_SR = 1, M32R_OPERAND_DR = 2, M32R_OPERAND_SRC1 = 3,
M32R_OPERAND_SRC2 = 4, M32R_OPERAND_SCR = 5, M32R_OPERAND_DCR = 6, M32R_OPERAND_SIMM8 = 7,
M32R_OPERAND_SIMM16 = 8, M32R_OPERAND_UIMM4 = 9, M32R_OPERAND_UIMM5 = 10, M32R_OPERAND_UIMM16 = 11,
M32R_OPERAND_ACC_S = 12, M32R_OPERAND_ACC = 13, M32R_OPERAND_HI16 = 14, M32R_OPERAND_SLO16 = 15,
M32R_OPERAND_ULO16 = 16, M32R_OPERAND_UIMM24 = 17, M32R_OPERAND_DISP8 = 18, M32R_OPERAND_DISP16 = 19,
M32R_OPERAND_DISP24 = 20, M32R_OPERAND_CONDBIT = 21, M32R_OPERAND_ACCUM = 22, M32R_OPERAND_ABORT_PARALLEL_EXECUTION = 23
} CGEN_OPERAND_TYPE;
/* Non-boolean attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
MACH_M32R = 0, MACH_M32RX = 1
} MACH_ATTR;
/* Enum declaration for parallel execution pipeline selection. */
typedef enum pipe_attr {
PIPE_NONE = 0, PIPE_O = 1, PIPE_S = 2, PIPE_OS = 3
} PIPE_ATTR;
/* Operand and instruction attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_FAKE, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_PC,
CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_RELAX, CGEN_OPERAND_RELOC, CGEN_OPERAND_SIGN_OPT,
CGEN_OPERAND_UNSIGNED
} CGEN_OPERAND_ATTR;
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_MACH, CGEN_INSN_PIPE, CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI,
CGEN_INSN_FILL_SLOT, CGEN_INSN_PARALLEL, CGEN_INSN_RELAX, CGEN_INSN_RELAX_BC,
CGEN_INSN_RELAX_BCL, CGEN_INSN_RELAX_BL, CGEN_INSN_RELAX_BNC, CGEN_INSN_RELAX_BNCL,
CGEN_INSN_RELAX_BRA, CGEN_INSN_RELAXABLE, CGEN_INSN_UNCOND_CTI
} CGEN_INSN_ATTR;
/* Insn types are used by the simulator. */
/* Enum declaration for m32r instruction types. */
typedef enum cgen_insn_type {
M32R_INSN_ILLEGAL, M32R_INSN_ADD, M32R_INSN_ADD3, M32R_INSN_AND,
M32R_INSN_AND3, M32R_INSN_OR, M32R_INSN_OR3, M32R_INSN_XOR,
M32R_INSN_XOR3, M32R_INSN_ADDI, M32R_INSN_ADDV, M32R_INSN_ADDV3,
M32R_INSN_ADDX, M32R_INSN_BC8, M32R_INSN_BC8_S, M32R_INSN_BC24,
M32R_INSN_BC24_L, M32R_INSN_BEQ, M32R_INSN_BEQZ, M32R_INSN_BGEZ,
M32R_INSN_BGTZ, M32R_INSN_BLEZ, M32R_INSN_BLTZ, M32R_INSN_BNEZ,
M32R_INSN_BL8, M32R_INSN_BL8_S, M32R_INSN_BL24, M32R_INSN_BL24_L,
M32R_INSN_BCL8, M32R_INSN_BCL8_S, M32R_INSN_BCL24, M32R_INSN_BCL24_L,
M32R_INSN_BNC8, M32R_INSN_BNC8_S, M32R_INSN_BNC24, M32R_INSN_BNC24_L,
M32R_INSN_BNE, M32R_INSN_BRA8, M32R_INSN_BRA8_S, M32R_INSN_BRA24,
M32R_INSN_BRA24_L, M32R_INSN_BNCL8, M32R_INSN_BNCL8_S, M32R_INSN_BNCL24,
M32R_INSN_BNCL24_L, M32R_INSN_CMP, M32R_INSN_CMPI, M32R_INSN_CMPU,
M32R_INSN_CMPUI, M32R_INSN_CMPEQ, M32R_INSN_CMPZ, M32R_INSN_DIV,
M32R_INSN_DIVU, M32R_INSN_REM, M32R_INSN_REMU, M32R_INSN_JC,
M32R_INSN_JNC, M32R_INSN_JL, M32R_INSN_JMP, M32R_INSN_LD,
M32R_INSN_LD_2, M32R_INSN_LD_D, M32R_INSN_LD_D2, M32R_INSN_LDB,
M32R_INSN_LDB_2, M32R_INSN_LDB_D, M32R_INSN_LDB_D2, M32R_INSN_LDH,
M32R_INSN_LDH_2, M32R_INSN_LDH_D, M32R_INSN_LDH_D2, M32R_INSN_LDUB,
M32R_INSN_LDUB_2, M32R_INSN_LDUB_D, M32R_INSN_LDUB_D2, M32R_INSN_LDUH,
M32R_INSN_LDUH_2, M32R_INSN_LDUH_D, M32R_INSN_LDUH_D2, M32R_INSN_LD_PLUS,
M32R_INSN_LD24, M32R_INSN_LDI8, M32R_INSN_LDI8A, M32R_INSN_LDI16,
M32R_INSN_LDI16A, M32R_INSN_LOCK, M32R_INSN_MACHI, M32R_INSN_MACHI_A,
M32R_INSN_MACLO, M32R_INSN_MACLO_A, M32R_INSN_MACWHI, M32R_INSN_MACWHI_A,
M32R_INSN_MACWLO, M32R_INSN_MACWLO_A, M32R_INSN_MUL, M32R_INSN_MULHI,
M32R_INSN_MULHI_A, M32R_INSN_MULLO, M32R_INSN_MULLO_A, M32R_INSN_MULWHI,
M32R_INSN_MULWHI_A, M32R_INSN_MULWLO, M32R_INSN_MULWLO_A, M32R_INSN_MV,
M32R_INSN_MVFACHI, M32R_INSN_MVFACHI_A, M32R_INSN_MVFACLO, M32R_INSN_MVFACLO_A,
M32R_INSN_MVFACMI, M32R_INSN_MVFACMI_A, M32R_INSN_MVFC, M32R_INSN_MVTACHI,
M32R_INSN_MVTACHI_A, M32R_INSN_MVTACLO, M32R_INSN_MVTACLO_A, M32R_INSN_MVTC,
M32R_INSN_NEG, M32R_INSN_NOP, M32R_INSN_NOT, M32R_INSN_RAC,
M32R_INSN_RAC_A, M32R_INSN_RACH, M32R_INSN_RACH_A, M32R_INSN_RTE,
M32R_INSN_SETH, M32R_INSN_SLL, M32R_INSN_SLL3, M32R_INSN_SLLI,
M32R_INSN_SRA, M32R_INSN_SRA3, M32R_INSN_SRAI, M32R_INSN_SRL,
M32R_INSN_SRL3, M32R_INSN_SRLI, M32R_INSN_ST, M32R_INSN_ST_2,
M32R_INSN_ST_D, M32R_INSN_ST_D2, M32R_INSN_STB, M32R_INSN_STB_2,
M32R_INSN_STB_D, M32R_INSN_STB_D2, M32R_INSN_STH, M32R_INSN_STH_2,
M32R_INSN_STH_D, M32R_INSN_STH_D2, M32R_INSN_ST_PLUS, M32R_INSN_ST_MINUS,
M32R_INSN_SUB, M32R_INSN_SUBV, M32R_INSN_SUBX, M32R_INSN_TRAP,
M32R_INSN_UNLOCK, M32R_INSN_PUSH, M32R_INSN_POP, M32R_INSN_SATB,
M32R_INSN_SATH, M32R_INSN_SAT, M32R_INSN_PCMPBZ, M32R_INSN_SADD,
M32R_INSN_MACWU1, M32R_INSN_MSBLO, M32R_INSN_MULWU1, M32R_INSN_MACHL1,
M32R_INSN_SC, M32R_INSN_SNC, M32R_INSN_MAX
} CGEN_INSN_TYPE;
/* Index of `illegal' insn place holder. */
#define CGEN_INSN_ILLEGAL M32R_INSN_ILLEGAL
/* Total number of insns in table. */
#define CGEN_MAX_INSNS ((int) M32R_INSN_MAX)
/* cgen.h uses things we just defined. */
#include "opcode/cgen.h"
/* This struct records data prior to insertion or after extraction. */
typedef struct cgen_fields {
long f_nil;
long f_op1;
long f_op2;
long f_cond;
long f_r1;
long f_r2;
long f_simm8;
long f_simm16;
long f_shift_op2;
long f_uimm4;
long f_uimm5;
long f_uimm16;
long f_uimm24;
long f_hi16;
long f_disp8;
long f_disp16;
long f_disp24;
long f_op23;
long f_op3;
long f_acc;
long f_acc_s;
int length;
} CGEN_FIELDS;
/* Attributes. */
extern const CGEN_ATTR_TABLE m32r_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE m32r_cgen_insn_attr_table[];
extern CGEN_KEYWORD m32r_cgen_opval_mach;
extern CGEN_KEYWORD m32r_cgen_opval_h_gr;
extern CGEN_KEYWORD m32r_cgen_opval_h_cr;
extern CGEN_KEYWORD m32r_cgen_opval_h_accums;
#define CGEN_INIT_PARSE() \
{\
}
#define CGEN_INIT_INSERT() \
{\
}
#define CGEN_INIT_EXTRACT() \
{\
}
#define CGEN_INIT_PRINT() \
{\
}
/* -- opc.h */
#undef CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 256
#undef CGEN_DIS_HASH
#define X(b) (((unsigned char *) (b))[0] & 0xf0)
#define CGEN_DIS_HASH(buffer, insn) \
(X (buffer) | \
(X (buffer) == 0x40 || X (buffer) == 0xe0 || X (buffer) == 0x60 || X (buffer) == 0x50 ? 0 \
: X (buffer) == 0x70 || X (buffer) == 0xf0 ? (((unsigned char *) (buffer))[0] & 0xf) \
: ((((unsigned char *) (buffer))[1] & 0xf0) >> 4)))
/* -- */
#endif /* m32r_OPC_H */