#undef CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 256
#undef CGEN_DIS_HASH
#if 0
#define X(b) (((unsigned char *) (b))[0] & 0xf0)
#define CGEN_DIS_HASH(buffer, value) \
(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) \
: X (buffer) == 0x30 ? ((((unsigned char *) (buffer))[1] & 0x70) >> 4) \
: ((((unsigned char *) (buffer))[1] & 0xf0) >> 4)))
#else
#define CGEN_DIS_HASH(buffer, value) m32r_cgen_dis_hash(buffer, value)
extern unsigned int m32r_cgen_dis_hash(const char *, CGEN_INSN_INT);
#endif
unsigned int
m32r_cgen_dis_hash (buf, value)
const char * buf ATTRIBUTE_UNUSED;
CGEN_INSN_INT value;
{
unsigned int x;
if (value & 0xffff0000)
value = (value >> 16) & 0xffff;
x = (value>>8) & 0xf0;
if (x == 0x40 || x == 0xe0 || x == 0x60 || x == 0x50)
return x;
if (x == 0x70 || x == 0xf0)
return x | ((value>>8) & 0x0f);
if (x == 0x30)
return x | ((value & 0x70) >> 4);
else
return x | ((value & 0xf0) >> 4);
}
static const char * parse_hash
PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
static const char * parse_hi16
PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
static const char * parse_slo16
PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
static const char * parse_ulo16
PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
static const char *
parse_hash (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
const char **strp;
int opindex ATTRIBUTE_UNUSED;
unsigned long *valuep ATTRIBUTE_UNUSED;
{
if (**strp == '#')
++*strp;
return NULL;
}
static const char *
parse_hi16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
unsigned long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_vma value;
if (**strp == '#')
++*strp;
if (strncasecmp (*strp, "high(", 5) == 0)
{
*strp += 5;
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
&result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
value >>= 16;
*valuep = value;
return errmsg;
}
else if (strncasecmp (*strp, "shigh(", 6) == 0)
{
*strp += 6;
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
&result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
{
value = value + (value & 0x8000 ? 0x10000 : 0);
value >>= 16;
}
*valuep = value;
return errmsg;
}
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
}
static const char *
parse_slo16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_vma value;
if (**strp == '#')
++*strp;
if (strncasecmp (*strp, "low(", 4) == 0)
{
*strp += 4;
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
&result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
{
value &= 0xffff;
if (value & 0x8000)
value |= 0xffff0000;
}
*valuep = value;
return errmsg;
}
if (strncasecmp (*strp, "sda(", 4) == 0)
{
*strp += 4;
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16,
NULL, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
*valuep = value;
return errmsg;
}
return cgen_parse_signed_integer (cd, strp, opindex, valuep);
}
static const char *
parse_ulo16 (cd, strp, opindex, valuep)
CGEN_CPU_DESC cd;
const char **strp;
int opindex;
unsigned long *valuep;
{
const char *errmsg;
enum cgen_parse_operand_result result_type;
bfd_vma value;
if (**strp == '#')
++*strp;
if (strncasecmp (*strp, "low(", 4) == 0)
{
*strp += 4;
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
&result_type, &value);
if (**strp != ')')
return "missing `)'";
++*strp;
if (errmsg == NULL
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
value &= 0xffff;
*valuep = value;
return errmsg;
}
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
}
static void print_hash PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
static int my_print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
#define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length) \
do \
{ \
if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_HASH_PREFIX)) \
(*info->fprintf_func) (info->stream, "#"); \
} \
while (0)
static void
print_hash (cd, dis_info, value, attrs, pc, length)
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
PTR dis_info;
long value ATTRIBUTE_UNUSED;
unsigned int attrs ATTRIBUTE_UNUSED;
bfd_vma pc ATTRIBUTE_UNUSED;
int length ATTRIBUTE_UNUSED;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "#");
}
#undef CGEN_PRINT_INSN
#define CGEN_PRINT_INSN my_print_insn
static int
my_print_insn (cd, pc, info)
CGEN_CPU_DESC cd;
bfd_vma pc;
disassemble_info *info;
{
char buffer[CGEN_MAX_INSN_SIZE];
char *buf = buffer;
int status;
int buflen = (pc & 3) == 0 ? 4 : 2;
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
char *x;
status = (*info->read_memory_func) (pc - ((!big_p && (pc & 3) != 0) ? 2 : 0),
buf, buflen, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return -1;
}
x = (big_p ? &buf[0] : &buf[3]);
if ((pc & 3) == 0 && (*x & 0x80) != 0)
return print_insn (cd, pc, info, buf, buflen);
if ((pc & 3) == 0)
{
buf += (big_p ? 0 : 2);
if (print_insn (cd, pc, info, buf, 2) == 0)
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
buf += (big_p ? 2 : -2);
}
x = (big_p ? &buf[0] : &buf[1]);
if (*x & 0x80)
{
(*info->fprintf_func) (info->stream, " || ");
*x &= 0x7f;
}
else
(*info->fprintf_func) (info->stream, " -> ");
if (print_insn (cd, pc & ~ (bfd_vma) 3, info, buf, 2) == 0)
(*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
return (pc & 3) ? 2 : 4;
}