backout m32rx stuff, not ready to be checked in
This commit is contained in:
parent
3bdf92bdc8
commit
853713a768
8 changed files with 1097 additions and 1530 deletions
|
@ -87,9 +87,7 @@ hppa-dis.c
|
|||
i386-dis.c
|
||||
i960-dis.c
|
||||
m32r-asm.c
|
||||
m32r-asm.in
|
||||
m32r-dis.c
|
||||
m32r-dis.in
|
||||
m32r-opc.c
|
||||
m32r-opc.h
|
||||
m68k-dis.c
|
||||
|
|
|
@ -1,22 +1,3 @@
|
|||
Thu Jan 15 10:32:06 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* m32r-dis.c (print_insn): Only look for parallel 16 bit
|
||||
instructions on a 32 bit boundary.
|
||||
|
||||
Wed Jan 14 17:37:03 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* m32r-asm.in: Generated file imported from cgen.
|
||||
* 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
|
||||
Tue Jan 13 09:21:56 1998 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
|
|
|
@ -56,10 +56,13 @@ static void insert_insn_normal
|
|||
|
||||
static CGEN_INLINE void
|
||||
insert_normal (value, attrs, start, length, shift, total_length, buffer)
|
||||
long value;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
int start, length, shift, total_length;
|
||||
char *buffer;
|
||||
int start;
|
||||
int length;
|
||||
int shift;
|
||||
int total_length;
|
||||
char * buffer;
|
||||
{
|
||||
bfd_vma x;
|
||||
|
||||
|
@ -70,7 +73,7 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
|
|||
switch (total_length)
|
||||
{
|
||||
case 8:
|
||||
x = *(unsigned char *) buffer;
|
||||
x = * (unsigned char *) buffer;
|
||||
break;
|
||||
case 16:
|
||||
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
|
||||
|
@ -99,7 +102,7 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
|
|||
switch (total_length)
|
||||
{
|
||||
case 8:
|
||||
*buffer = value;
|
||||
* buffer = value;
|
||||
break;
|
||||
case 16:
|
||||
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
|
||||
|
@ -120,6 +123,404 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
|
|||
}
|
||||
|
||||
/* -- 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;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
|
||||
/* FIXME: Need # in assembler syntax (means '#' is optional). */
|
||||
if (**strp == '#')
|
||||
++*strp;
|
||||
|
||||
if (strncmp (*strp, "high(", 5) == 0)
|
||||
{
|
||||
*strp += 5;
|
||||
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_ULO,
|
||||
&result_type, valuep);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
*valuep >>= 16;
|
||||
return errmsg;
|
||||
}
|
||||
else if (strncmp (*strp, "shigh(", 6) == 0)
|
||||
{
|
||||
*strp += 6;
|
||||
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_SLO,
|
||||
&result_type, valuep);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
*valuep = (*valuep >> 16) + ((*valuep) & 0x8000 ? 1 : 0);
|
||||
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;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
|
||||
/* 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,
|
||||
&result_type, 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, NULL, 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;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
|
||||
/* 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,
|
||||
&result_type, 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;
|
||||
CGEN_FIELDS * fields;
|
||||
{
|
||||
const char * errmsg;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case M32R_OPERAND_SR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
|
||||
break;
|
||||
case M32R_OPERAND_DR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
|
||||
break;
|
||||
case M32R_OPERAND_SRC1 :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
|
||||
break;
|
||||
case M32R_OPERAND_SRC2 :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
|
||||
break;
|
||||
case M32R_OPERAND_SCR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r2);
|
||||
break;
|
||||
case M32R_OPERAND_DCR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r1);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM8 :
|
||||
errmsg = cgen_parse_signed_integer (strp, 7, -128, 127, &fields->f_simm8);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM16 :
|
||||
errmsg = cgen_parse_signed_integer (strp, 8, -32768, 32767, &fields->f_simm16);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM4 :
|
||||
errmsg = cgen_parse_unsigned_integer (strp, 9, 0, 15, &fields->f_uimm4);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM5 :
|
||||
errmsg = cgen_parse_unsigned_integer (strp, 10, 0, 31, &fields->f_uimm5);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM16 :
|
||||
errmsg = cgen_parse_unsigned_integer (strp, 11, 0, 65535, &fields->f_uimm16);
|
||||
break;
|
||||
case M32R_OPERAND_HI16 :
|
||||
errmsg = parse_h_hi16 (strp, 12, 0, 65535, &fields->f_hi16);
|
||||
break;
|
||||
case M32R_OPERAND_SLO16 :
|
||||
errmsg = parse_h_slo16 (strp, 13, -32768, 32767, &fields->f_simm16);
|
||||
break;
|
||||
case M32R_OPERAND_ULO16 :
|
||||
errmsg = parse_h_ulo16 (strp, 14, 0, 65535, &fields->f_uimm16);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM24 :
|
||||
errmsg = cgen_parse_address (strp, 15, 0, NULL, & fields->f_uimm24);
|
||||
break;
|
||||
case M32R_OPERAND_DISP8 :
|
||||
errmsg = cgen_parse_address (strp, 16, 0, NULL, & fields->f_disp8);
|
||||
break;
|
||||
case M32R_OPERAND_DISP16 :
|
||||
errmsg = cgen_parse_address (strp, 17, 0, NULL, & fields->f_disp16);
|
||||
break;
|
||||
case M32R_OPERAND_DISP24 :
|
||||
errmsg = cgen_parse_address (strp, 18, 0, NULL, & 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;
|
||||
CGEN_FIELDS * fields;
|
||||
cgen_insn_t * buffer;
|
||||
{
|
||||
switch (opindex)
|
||||
{
|
||||
case M32R_OPERAND_SR :
|
||||
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_DR :
|
||||
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SRC1 :
|
||||
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SRC2 :
|
||||
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SCR :
|
||||
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_DCR :
|
||||
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM8 :
|
||||
insert_normal (fields->f_simm8, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM16 :
|
||||
insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM4 :
|
||||
insert_normal (fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM5 :
|
||||
insert_normal (fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM16 :
|
||||
insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_HI16 :
|
||||
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 M32R_OPERAND_SLO16 :
|
||||
insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_ULO16 :
|
||||
insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM24 :
|
||||
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 M32R_OPERAND_DISP8 :
|
||||
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 M32R_OPERAND_DISP16 :
|
||||
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 M32R_OPERAND_DISP24 :
|
||||
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 CGEN_FIELDS * fields;
|
||||
{
|
||||
const char * errmsg = NULL;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case M32R_OPERAND_SR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SRC1 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SRC2 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SCR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DCR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SIMM8 :
|
||||
errmsg = cgen_validate_signed_integer (fields->f_simm8, -128, 127);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM16 :
|
||||
errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM4 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm4, 0, 15);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM5 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm5, 0, 31);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM16 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
|
||||
break;
|
||||
case M32R_OPERAND_HI16 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_hi16, 0, 65535);
|
||||
break;
|
||||
case M32R_OPERAND_SLO16 :
|
||||
errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
|
||||
break;
|
||||
case M32R_OPERAND_ULO16 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM24 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DISP8 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DISP16 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DISP24 :
|
||||
/* 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.
|
||||
|
||||
|
@ -137,25 +538,25 @@ insert_normal (value, attrs, start, length, shift, total_length, buffer)
|
|||
|
||||
static const char *
|
||||
parse_insn_normal (insn, strp, fields)
|
||||
const CGEN_INSN *insn;
|
||||
const char **strp;
|
||||
CGEN_FIELDS *fields;
|
||||
const CGEN_INSN * insn;
|
||||
const char ** strp;
|
||||
CGEN_FIELDS * fields;
|
||||
{
|
||||
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
|
||||
const char *str = *strp;
|
||||
const char *errmsg;
|
||||
const char *p;
|
||||
const unsigned char *syn;
|
||||
const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
|
||||
const char * str = *strp;
|
||||
const char * errmsg;
|
||||
const char * p;
|
||||
const unsigned char * syn;
|
||||
#ifdef CGEN_MNEMONIC_OPERANDS
|
||||
int past_opcode_p;
|
||||
int past_opcode_p;
|
||||
#endif
|
||||
|
||||
/* For now we assume the mnemonic is first (there are no leading operands).
|
||||
We can parse it without needing to set up operand parsing. */
|
||||
p = CGEN_INSN_MNEMONIC (insn);
|
||||
while (*p && *p == *str)
|
||||
++p, ++str;
|
||||
if (*p || (*str && !isspace (*str)))
|
||||
while (* p && * p == * str)
|
||||
++ p, ++ str;
|
||||
if (* p || (* str && !isspace (* str)))
|
||||
return "unrecognized instruction";
|
||||
|
||||
CGEN_INIT_PARSE ();
|
||||
|
@ -167,24 +568,27 @@ parse_insn_normal (insn, strp, fields)
|
|||
/* We don't check for (*str != '\0') here because we want to parse
|
||||
any trailing fake arguments in the syntax string. */
|
||||
syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
|
||||
|
||||
/* Mnemonics come first for now, ensure valid string. */
|
||||
if (! CGEN_SYNTAX_MNEMONIC_P (*syn))
|
||||
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
|
||||
abort ();
|
||||
|
||||
++syn;
|
||||
while (*syn != 0)
|
||||
|
||||
while (* syn != 0)
|
||||
{
|
||||
/* Non operand chars must match exactly. */
|
||||
/* FIXME: Need to better handle whitespace. */
|
||||
if (CGEN_SYNTAX_CHAR_P (*syn))
|
||||
if (CGEN_SYNTAX_CHAR_P (* syn))
|
||||
{
|
||||
if (*str == CGEN_SYNTAX_CHAR (*syn))
|
||||
if (*str == CGEN_SYNTAX_CHAR (* syn))
|
||||
{
|
||||
#ifdef CGEN_MNEMONIC_OPERANDS
|
||||
if (*syn == ' ')
|
||||
if (* syn == ' ')
|
||||
past_opcode_p = 1;
|
||||
#endif
|
||||
++syn;
|
||||
++str;
|
||||
++ syn;
|
||||
++ str;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -202,20 +606,20 @@ parse_insn_normal (insn, strp, fields)
|
|||
return errmsg;
|
||||
|
||||
/* Done with this operand, continue with next one. */
|
||||
++syn;
|
||||
++ syn;
|
||||
}
|
||||
|
||||
/* If we're at the end of the syntax string, we're done. */
|
||||
if (*syn == '\0')
|
||||
if (* syn == '\0')
|
||||
{
|
||||
/* FIXME: For the moment we assume a valid `str' can only contain
|
||||
blanks now. IE: We needn't try again with a longer version of
|
||||
the insn and it is assumed that longer versions of insns appear
|
||||
before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
|
||||
while (isspace (*str))
|
||||
++str;
|
||||
while (isspace (* str))
|
||||
++ str;
|
||||
|
||||
if (*str != '\0')
|
||||
if (* str != '\0')
|
||||
return "junk at end of line"; /* FIXME: would like to include `str' */
|
||||
|
||||
return NULL;
|
||||
|
@ -230,13 +634,13 @@ parse_insn_normal (insn, strp, fields)
|
|||
|
||||
static void
|
||||
insert_insn_normal (insn, fields, buffer)
|
||||
const CGEN_INSN *insn;
|
||||
CGEN_FIELDS *fields;
|
||||
cgen_insn_t *buffer;
|
||||
const CGEN_INSN * insn;
|
||||
CGEN_FIELDS * fields;
|
||||
cgen_insn_t * buffer;
|
||||
{
|
||||
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
|
||||
bfd_vma value;
|
||||
const unsigned char *syn;
|
||||
const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
|
||||
bfd_vma value;
|
||||
const unsigned char * syn;
|
||||
|
||||
CGEN_INIT_INSERT ();
|
||||
value = CGEN_INSN_VALUE (insn);
|
||||
|
@ -251,7 +655,7 @@ insert_insn_normal (insn, fields, buffer)
|
|||
switch (min (CGEN_BASE_INSN_BITSIZE, CGEN_FIELDS_BITSIZE (fields)))
|
||||
{
|
||||
case 8:
|
||||
*buffer = value;
|
||||
* buffer = value;
|
||||
break;
|
||||
case 16:
|
||||
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
|
||||
|
@ -273,9 +677,9 @@ insert_insn_normal (insn, fields, buffer)
|
|||
/* ??? Rather than scanning the syntax string again, we could store
|
||||
in `fields' a null terminated list of the fields that are present. */
|
||||
|
||||
for (syn = CGEN_SYNTAX_STRING (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;
|
||||
|
||||
m32r_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields, buffer);
|
||||
|
@ -292,17 +696,17 @@ insert_insn_normal (insn, fields, buffer)
|
|||
|
||||
const CGEN_INSN *
|
||||
m32r_cgen_assemble_insn (str, fields, buf, errmsg)
|
||||
const char *str;
|
||||
CGEN_FIELDS *fields;
|
||||
cgen_insn_t *buf;
|
||||
char **errmsg;
|
||||
const char * str;
|
||||
CGEN_FIELDS * fields;
|
||||
cgen_insn_t * buf;
|
||||
char ** errmsg;
|
||||
{
|
||||
const char *start;
|
||||
CGEN_INSN_LIST *ilist;
|
||||
const char * start;
|
||||
CGEN_INSN_LIST * ilist;
|
||||
|
||||
/* Skip leading white space. */
|
||||
while (isspace (*str))
|
||||
++str;
|
||||
while (isspace (* str))
|
||||
++ str;
|
||||
|
||||
/* The instructions are stored in hashed lists.
|
||||
Get the first in the list. */
|
||||
|
@ -343,9 +747,9 @@ m32r_cgen_assemble_insn (str, fields, buf, errmsg)
|
|||
inline functions but of course that would only work for gcc. Since
|
||||
we're machine generating some code we could do that here too. Maybe
|
||||
later. */
|
||||
if (! (*CGEN_PARSE_FN (insn)) (insn, &str, fields))
|
||||
if (! CGEN_PARSE_FN (insn) (insn, & str, fields))
|
||||
{
|
||||
(*CGEN_INSERT_FN (insn)) (insn, fields, buf);
|
||||
CGEN_INSERT_FN (insn) (insn, fields, buf);
|
||||
/* It is up to the caller to actually output the insn and any
|
||||
queued relocs. */
|
||||
return insn;
|
||||
|
@ -376,12 +780,12 @@ m32r_cgen_assemble_insn (str, fields, buf, errmsg)
|
|||
|
||||
void
|
||||
m32r_cgen_asm_hash_keywords (opvals)
|
||||
CGEN_KEYWORD *opvals;
|
||||
CGEN_KEYWORD * opvals;
|
||||
{
|
||||
CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
|
||||
const 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)
|
||||
{
|
||||
#if 0 /* Unnecessary, should be done in the search routine. */
|
||||
if (! m32r_cgen_opval_supported (ke))
|
||||
|
|
|
@ -1,416 +0,0 @@
|
|||
/* -- 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;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
|
||||
/* FIXME: Need # in assembler syntax (means '#' is optional). */
|
||||
if (**strp == '#')
|
||||
++*strp;
|
||||
|
||||
if (strncmp (*strp, "high(", 5) == 0)
|
||||
{
|
||||
*strp += 5;
|
||||
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_ULO,
|
||||
&result_type, valuep);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
*valuep >>= 16;
|
||||
return errmsg;
|
||||
}
|
||||
else if (strncmp (*strp, "shigh(", 6) == 0)
|
||||
{
|
||||
*strp += 6;
|
||||
errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_SLO,
|
||||
&result_type, valuep);
|
||||
if (**strp != ')')
|
||||
return "missing `)'";
|
||||
++*strp;
|
||||
if (errmsg == NULL
|
||||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
|
||||
*valuep = (*valuep >> 16) + ((*valuep) & 0x8000 ? 1 : 0);
|
||||
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;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
|
||||
/* 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,
|
||||
&result_type, 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, NULL, 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;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
|
||||
/* 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,
|
||||
&result_type, 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;
|
||||
CGEN_FIELDS *fields;
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case M32R_OPERAND_SR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r2);
|
||||
break;
|
||||
case M32R_OPERAND_DR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r1);
|
||||
break;
|
||||
case M32R_OPERAND_SRC1 :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r1);
|
||||
break;
|
||||
case M32R_OPERAND_SRC2 :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, &fields->f_r2);
|
||||
break;
|
||||
case M32R_OPERAND_SCR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, &fields->f_r2);
|
||||
break;
|
||||
case M32R_OPERAND_DCR :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, &fields->f_r1);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM8 :
|
||||
errmsg = cgen_parse_signed_integer (strp, 7, -128, 127, &fields->f_simm8);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM16 :
|
||||
errmsg = cgen_parse_signed_integer (strp, 8, -32768, 32767, &fields->f_simm16);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM4 :
|
||||
errmsg = cgen_parse_unsigned_integer (strp, 9, 0, 15, &fields->f_uimm4);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM5 :
|
||||
errmsg = cgen_parse_unsigned_integer (strp, 10, 0, 31, &fields->f_uimm5);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM16 :
|
||||
errmsg = cgen_parse_unsigned_integer (strp, 11, 0, 65535, &fields->f_uimm16);
|
||||
break;
|
||||
case M32R_OPERAND_ACC_S :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, &fields->f_acc_s);
|
||||
break;
|
||||
case M32R_OPERAND_ACC :
|
||||
errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, &fields->f_acc);
|
||||
break;
|
||||
case M32R_OPERAND_HI16 :
|
||||
errmsg = parse_h_hi16 (strp, 14, 0, 65535, &fields->f_hi16);
|
||||
break;
|
||||
case M32R_OPERAND_SLO16 :
|
||||
errmsg = parse_h_slo16 (strp, 15, -32768, 32767, &fields->f_simm16);
|
||||
break;
|
||||
case M32R_OPERAND_ULO16 :
|
||||
errmsg = parse_h_ulo16 (strp, 16, 0, 65535, &fields->f_uimm16);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM24 :
|
||||
errmsg = cgen_parse_address (strp, 17, 0, NULL, &fields->f_uimm24);
|
||||
break;
|
||||
case M32R_OPERAND_DISP8 :
|
||||
errmsg = cgen_parse_address (strp, 18, 0, NULL, &fields->f_disp8);
|
||||
break;
|
||||
case M32R_OPERAND_DISP16 :
|
||||
errmsg = cgen_parse_address (strp, 19, 0, NULL, &fields->f_disp16);
|
||||
break;
|
||||
case M32R_OPERAND_DISP24 :
|
||||
errmsg = cgen_parse_address (strp, 20, 0, NULL, &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;
|
||||
CGEN_FIELDS *fields;
|
||||
cgen_insn_t *buffer;
|
||||
{
|
||||
switch (opindex)
|
||||
{
|
||||
case M32R_OPERAND_SR :
|
||||
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_DR :
|
||||
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SRC1 :
|
||||
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SRC2 :
|
||||
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SCR :
|
||||
insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_DCR :
|
||||
insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM8 :
|
||||
insert_normal (fields->f_simm8, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM16 :
|
||||
insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM4 :
|
||||
insert_normal (fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM5 :
|
||||
insert_normal (fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM16 :
|
||||
insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_ACC_S :
|
||||
insert_normal (fields->f_acc_s, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_ACC :
|
||||
insert_normal (fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_HI16 :
|
||||
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 M32R_OPERAND_SLO16 :
|
||||
insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_ULO16 :
|
||||
insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM24 :
|
||||
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 M32R_OPERAND_DISP8 :
|
||||
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 M32R_OPERAND_DISP16 :
|
||||
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 M32R_OPERAND_DISP24 :
|
||||
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 CGEN_FIELDS *fields;
|
||||
{
|
||||
const char *errmsg = NULL;
|
||||
|
||||
switch (opindex)
|
||||
{
|
||||
case M32R_OPERAND_SR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SRC1 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SRC2 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SCR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DCR :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_SIMM8 :
|
||||
errmsg = cgen_validate_signed_integer (fields->f_simm8, -128, 127);
|
||||
break;
|
||||
case M32R_OPERAND_SIMM16 :
|
||||
errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM4 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm4, 0, 15);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM5 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm5, 0, 31);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM16 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
|
||||
break;
|
||||
case M32R_OPERAND_ACC_S :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_ACC :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_HI16 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_hi16, 0, 65535);
|
||||
break;
|
||||
case M32R_OPERAND_SLO16 :
|
||||
errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
|
||||
break;
|
||||
case M32R_OPERAND_ULO16 :
|
||||
errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
|
||||
break;
|
||||
case M32R_OPERAND_UIMM24 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DISP8 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DISP16 :
|
||||
/* nothing to do */
|
||||
break;
|
||||
case M32R_OPERAND_DISP24 :
|
||||
/* 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 ();
|
||||
}
|
||||
|
|
@ -49,11 +49,6 @@ static int extract_insn_normal
|
|||
PARAMS ((const CGEN_INSN *, void *, cgen_insn_t, CGEN_FIELDS *));
|
||||
static void print_insn_normal
|
||||
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.
|
||||
|
||||
|
@ -62,14 +57,11 @@ m32r_cgen_print_operand
|
|||
|
||||
static int
|
||||
extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length, valuep)
|
||||
void * buf_ctrl;
|
||||
cgen_insn_t insn_value;
|
||||
void *buf_ctrl;
|
||||
cgen_insn_t insn_value;
|
||||
unsigned int attrs;
|
||||
int start;
|
||||
int length;
|
||||
int shift;
|
||||
int total_length;
|
||||
long * valuep;
|
||||
int start, length, shift, total_length;
|
||||
long *valuep;
|
||||
{
|
||||
long value;
|
||||
|
||||
|
@ -94,7 +86,7 @@ extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length,
|
|||
else
|
||||
value <<= shift;
|
||||
|
||||
* valuep = value;
|
||||
*valuep = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -102,13 +94,13 @@ extract_normal (buf_ctrl, insn_value, attrs, start, length, shift, total_length,
|
|||
|
||||
static void
|
||||
print_normal (dis_info, value, attrs, pc, length)
|
||||
void * dis_info;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
void *dis_info;
|
||||
long value;
|
||||
unsigned int attrs;
|
||||
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. */
|
||||
if (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_FAKE))
|
||||
|
@ -129,19 +121,262 @@ print_normal (dis_info, value, attrs, pc, length)
|
|||
|
||||
static void
|
||||
print_keyword (dis_info, keyword_table, value, attrs)
|
||||
void * dis_info;
|
||||
CGEN_KEYWORD * keyword_table;
|
||||
long value;
|
||||
CGEN_ATTR * attrs;
|
||||
void *dis_info;
|
||||
CGEN_KEYWORD *keyword_table;
|
||||
long value;
|
||||
CGEN_ATTR *attrs;
|
||||
{
|
||||
disassemble_info * info = dis_info;
|
||||
const CGEN_KEYWORD_ENTRY * ke;
|
||||
disassemble_info *info = dis_info;
|
||||
const CGEN_KEYWORD_ENTRY *ke;
|
||||
|
||||
ke = cgen_keyword_lookup_value (keyword_table, value);
|
||||
info->fprintf_func (info->stream, "%s", ke == NULL ? "???" : ke->name);
|
||||
if (ke != NULL)
|
||||
(*info->fprintf_func) (info->stream, "%s", ke->name);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "???");
|
||||
}
|
||||
|
||||
/* -- 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;
|
||||
{
|
||||
/* 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_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_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 ();
|
||||
}
|
||||
|
||||
|
||||
/* Default insn extractor.
|
||||
|
||||
|
@ -151,26 +386,26 @@ print_keyword (dis_info, keyword_table, value, attrs)
|
|||
|
||||
static int
|
||||
extract_insn_normal (insn, buf_ctrl, insn_value, fields)
|
||||
const CGEN_INSN * insn;
|
||||
void * buf_ctrl;
|
||||
cgen_insn_t insn_value;
|
||||
CGEN_FIELDS * fields;
|
||||
const CGEN_INSN *insn;
|
||||
void *buf_ctrl;
|
||||
cgen_insn_t insn_value;
|
||||
CGEN_FIELDS *fields;
|
||||
{
|
||||
const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
|
||||
const unsigned char * syn;
|
||||
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
|
||||
const unsigned char *syn;
|
||||
|
||||
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
|
||||
|
||||
CGEN_INIT_EXTRACT ();
|
||||
|
||||
for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
|
||||
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (CGEN_SYNTAX_CHAR_P (* syn))
|
||||
if (CGEN_SYNTAX_CHAR_P (*syn))
|
||||
continue;
|
||||
|
||||
length = m32r_cgen_extract_operand (CGEN_SYNTAX_FIELD (* syn),
|
||||
length = m32r_cgen_extract_operand (CGEN_SYNTAX_FIELD (*syn),
|
||||
buf_ctrl, insn_value, fields);
|
||||
if (length == 0)
|
||||
return 0;
|
||||
|
@ -188,33 +423,33 @@ extract_insn_normal (insn, buf_ctrl, insn_value, fields)
|
|||
|
||||
static void
|
||||
print_insn_normal (dis_info, insn, fields, pc, length)
|
||||
void * dis_info;
|
||||
const CGEN_INSN * insn;
|
||||
CGEN_FIELDS * fields;
|
||||
bfd_vma pc;
|
||||
int length;
|
||||
void *dis_info;
|
||||
const CGEN_INSN *insn;
|
||||
CGEN_FIELDS *fields;
|
||||
bfd_vma pc;
|
||||
int length;
|
||||
{
|
||||
const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
|
||||
disassemble_info * info = dis_info;
|
||||
const unsigned char * syn;
|
||||
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
|
||||
disassemble_info *info = dis_info;
|
||||
const unsigned char *syn;
|
||||
|
||||
CGEN_INIT_PRINT ();
|
||||
|
||||
for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
|
||||
for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
|
||||
{
|
||||
if (CGEN_SYNTAX_MNEMONIC_P (* syn))
|
||||
if (CGEN_SYNTAX_MNEMONIC_P (*syn))
|
||||
{
|
||||
info->fprintf_func (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
|
||||
(*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
|
||||
continue;
|
||||
}
|
||||
if (CGEN_SYNTAX_CHAR_P (* syn))
|
||||
if (CGEN_SYNTAX_CHAR_P (*syn))
|
||||
{
|
||||
info->fprintf_func (info->stream, "%c", CGEN_SYNTAX_CHAR (* syn));
|
||||
(*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
@ -231,16 +466,15 @@ print_insn_normal (dis_info, insn, fields, pc, length)
|
|||
|
||||
static int
|
||||
print_insn (pc, info, buf, buflen)
|
||||
bfd_vma pc;
|
||||
disassemble_info * info;
|
||||
char * buf;
|
||||
int buflen;
|
||||
bfd_vma pc;
|
||||
disassemble_info *info;
|
||||
char *buf;
|
||||
int buflen;
|
||||
{
|
||||
int i;
|
||||
unsigned long insn_value;
|
||||
const CGEN_INSN_LIST * insn_list;
|
||||
int extra_bytes;
|
||||
|
||||
int i;
|
||||
unsigned long insn_value;
|
||||
const CGEN_INSN_LIST *insn_list;
|
||||
|
||||
switch (buflen)
|
||||
{
|
||||
case 8:
|
||||
|
@ -256,53 +490,16 @@ print_insn (pc, info, buf, buflen)
|
|||
abort ();
|
||||
}
|
||||
|
||||
/* Special case - a 32 bit instruction which is actually two 16 bit instructions
|
||||
being executed in parallel. */
|
||||
if (buflen == 32
|
||||
&& (pc & 0x3) == 0
|
||||
&& ((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.
|
||||
Pick the first one and keep trying until we find the right one. */
|
||||
|
||||
insn_list = CGEN_DIS_LOOKUP_INSN (buf, insn_value);
|
||||
|
||||
while (insn_list != NULL)
|
||||
{
|
||||
const CGEN_INSN * insn = insn_list->insn;
|
||||
unsigned long value;
|
||||
const CGEN_INSN *insn = insn_list->insn;
|
||||
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
|
||||
CGEN_FIELDS fields;
|
||||
int length;
|
||||
|
||||
#if 0 /* not needed as insn shouldn't be in hash lists if not supported */
|
||||
/* Supported by this cpu? */
|
||||
|
@ -310,43 +507,28 @@ print_insn (pc, info, buf, buflen)
|
|||
continue;
|
||||
#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. */
|
||||
/* ??? May wish to allow target to defer this check until the extract
|
||||
handler. */
|
||||
if ((value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
|
||||
if ((insn_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
|
||||
machine insn and extracts the fields. The second pass prints
|
||||
them. */
|
||||
|
||||
length = CGEN_EXTRACT_FN (insn) (insn, NULL, value, & fields);
|
||||
length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, &fields);
|
||||
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 */
|
||||
return (length / 8) + extra_bytes;
|
||||
return length / 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
insn_list = CGEN_DIS_NEXT_INSN (insn_list);
|
||||
}
|
||||
|
||||
return extra_bytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Main entry point.
|
||||
|
@ -355,41 +537,32 @@ print_insn (pc, info, buf, buflen)
|
|||
|
||||
int
|
||||
print_insn_m32r (pc, info)
|
||||
bfd_vma pc;
|
||||
disassemble_info * info;
|
||||
bfd_vma pc;
|
||||
disassemble_info *info;
|
||||
{
|
||||
char buffer [CGEN_MAX_INSN_SIZE];
|
||||
int status;
|
||||
int length;
|
||||
static int initialized = 0;
|
||||
static int current_mach = 0;
|
||||
static int current_bigend = 0;
|
||||
int mach = info->mach;
|
||||
int bigend = info->endian == BFD_ENDIAN_BIG;
|
||||
char buffer[CGEN_MAX_INSN_SIZE];
|
||||
int status, length;
|
||||
static int initialized = 0;
|
||||
static int current_mach = 0;
|
||||
static int current_big_p = 0;
|
||||
int mach = info->mach;
|
||||
int big_p = info->endian == BFD_ENDIAN_BIG;
|
||||
|
||||
/* If we haven't initialized yet, or if we've switched cpu's, initialize. */
|
||||
if (!initialized || mach != current_mach || bigend != current_bigend)
|
||||
if (!initialized || mach != current_mach || big_p != current_big_p)
|
||||
{
|
||||
initialized = 1;
|
||||
current_mach = mach;
|
||||
current_bigend = bigend;
|
||||
|
||||
m32r_cgen_init_dis (mach, bigend ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
|
||||
initialized = 1;
|
||||
current_mach = mach;
|
||||
current_big_p = big_p;
|
||||
m32r_cgen_init_dis (mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* 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);
|
||||
(*info->memory_error_func) (status, pc, info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -399,14 +572,9 @@ print_insn_m32r (pc, info)
|
|||
but if not possible try to move this hook elsewhere rather than
|
||||
have two hooks. */
|
||||
length = CGEN_PRINT_INSN (pc, info, buffer, CGEN_BASE_INSN_BITSIZE);
|
||||
|
||||
if (length)
|
||||
return length;
|
||||
|
||||
info->fprintf_func (info->stream, UNKNOWN_INSN_MSG);
|
||||
|
||||
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
|
||||
return CGEN_DEFAULT_INSN_SIZE;
|
||||
}
|
||||
|
||||
/* Get the generate machine specific code. */
|
||||
#include "m32r-dis.in"
|
||||
|
|
|
@ -1,252 +0,0 @@
|
|||
/* -- 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
|
@ -39,11 +39,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define CGEN_INT_INSN
|
||||
|
||||
/* +1 because the first entry is reserved (null) */
|
||||
#define CGEN_NUM_INSNS (165 + 1)
|
||||
#define CGEN_NUM_OPERANDS (24)
|
||||
#define CGEN_NUM_INSNS (127 + 1)
|
||||
#define CGEN_NUM_OPERANDS (21)
|
||||
|
||||
/* Number of non-boolean attributes. */
|
||||
#define CGEN_MAX_INSN_ATTRS 2
|
||||
#define CGEN_MAX_INSN_ATTRS 0
|
||||
#define CGEN_MAX_OPERAND_ATTRS 0
|
||||
|
||||
/* FIXME: Need to compute CGEN_MAX_SYNTAX_BYTES. */
|
||||
|
@ -54,7 +54,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define CGEN_MNEMONIC_OPERANDS
|
||||
|
||||
/* Number of architecture variants. */
|
||||
#define MAX_MACHS 2
|
||||
#define MAX_MACHS 1
|
||||
|
||||
/* Enums. */
|
||||
|
||||
|
@ -79,23 +79,18 @@ 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
|
||||
M32R_OPERAND_HI16 = 12, M32R_OPERAND_SLO16 = 13, M32R_OPERAND_ULO16 = 14, M32R_OPERAND_UIMM24 = 15,
|
||||
M32R_OPERAND_DISP8 = 16, M32R_OPERAND_DISP16 = 17, M32R_OPERAND_DISP24 = 18, M32R_OPERAND_CONDBIT = 19,
|
||||
M32R_OPERAND_ACCUM = 20
|
||||
} CGEN_OPERAND_TYPE;
|
||||
|
||||
/* Non-boolean attributes. */
|
||||
|
||||
/* Enum declaration for machine type selection. */
|
||||
typedef enum mach_attr {
|
||||
MACH_M32R = 0, MACH_M32RX = 1
|
||||
MACH_M32R = 0
|
||||
} 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. */
|
||||
|
@ -107,10 +102,9 @@ typedef enum 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_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_FILL_SLOT, CGEN_INSN_RELAX,
|
||||
CGEN_INSN_RELAX_BC, CGEN_INSN_RELAX_BL, CGEN_INSN_RELAX_BNC, CGEN_INSN_RELAX_BRA,
|
||||
CGEN_INSN_RELAXABLE, CGEN_INSN_UNCOND_CTI
|
||||
} CGEN_INSN_ATTR;
|
||||
|
||||
/* Insn types are used by the simulator. */
|
||||
|
@ -123,41 +117,32 @@ typedef enum cgen_insn_type {
|
|||
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_BRA24_L, M32R_INSN_CMP, M32R_INSN_CMPI, M32R_INSN_CMPU,
|
||||
M32R_INSN_CMPUI, M32R_INSN_DIV, M32R_INSN_DIVU, M32R_INSN_REM,
|
||||
M32R_INSN_REMU, 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
|
||||
M32R_INSN_LDI16A, M32R_INSN_LOCK, M32R_INSN_MACHI, M32R_INSN_MACLO,
|
||||
M32R_INSN_MACWHI, M32R_INSN_MACWLO, M32R_INSN_MUL, M32R_INSN_MULHI,
|
||||
M32R_INSN_MULLO, M32R_INSN_MULWHI, M32R_INSN_MULWLO, M32R_INSN_MV,
|
||||
M32R_INSN_MVFACHI, M32R_INSN_MVFACLO, M32R_INSN_MVFACMI, M32R_INSN_MVFC,
|
||||
M32R_INSN_MVTACHI, M32R_INSN_MVTACLO, M32R_INSN_MVTC, M32R_INSN_NEG,
|
||||
M32R_INSN_NOP, M32R_INSN_NOT, M32R_INSN_RAC, M32R_INSN_RACH,
|
||||
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_MAX
|
||||
} CGEN_INSN_TYPE;
|
||||
|
||||
/* Index of `illegal' insn place holder. */
|
||||
|
@ -169,8 +154,8 @@ typedef enum cgen_insn_type {
|
|||
#include "opcode/cgen.h"
|
||||
|
||||
/* This struct records data prior to insertion or after extraction. */
|
||||
typedef struct cgen_fields {
|
||||
long f_nil;
|
||||
typedef struct cgen_fields
|
||||
{ long f_nil;
|
||||
long f_op1;
|
||||
long f_op2;
|
||||
long f_cond;
|
||||
|
@ -187,10 +172,6 @@ typedef struct cgen_fields {
|
|||
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;
|
||||
|
||||
|
@ -201,7 +182,6 @@ 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() \
|
||||
{\
|
||||
|
|
Loading…
Add table
Reference in a new issue