Support for disassembling parallel instructions added.
Insn attributes hand patched until cgen can generate the correct values.
This commit is contained in:
parent
cc662e8676
commit
23cf992f4a
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
252
opcodes/m32r-dis.in
Normal 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 ();
|
||||||
|
}
|
||||||
|
|
1230
opcodes/m32r-opc.c
1230
opcodes/m32r-opc.c
File diff suppressed because it is too large
Load Diff
234
opcodes/m32r-opc.h
Normal file
234
opcodes/m32r-opc.h
Normal 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 */
|
Loading…
x
Reference in New Issue
Block a user