29 #include "libiberty.h"
34 #ifndef MAX_BYTES_PER_CRIS_INSN
35 #define MAX_BYTES_PER_CRIS_INSN 8
41 #define PARSE_PREFIX 1
45 #define REGISTER_PREFIX_CHAR '$'
69 #define TRACE_CASE (disdata->trace_case)
118 = (!
info->disassembler_options
119 || (strcmp (
info->disassembler_options,
"nocase") != 0));
175 unsigned int prefix_insn,
195 opc_table =
calloc (65536,
sizeof (opc_table[0]));
201 =
calloc (65536,
sizeof (dip_prefixes[0]));
207 =
calloc (65536,
sizeof (bdapq_m1_prefixes[0]));
208 if (!bdapq_m1_prefixes) {
213 =
calloc (65536,
sizeof (bdapq_m2_prefixes[0]));
214 if (!bdapq_m2_prefixes) {
219 =
calloc (65536,
sizeof (bdapq_m4_prefixes[0]));
220 if (!bdapq_m4_prefixes) {
225 =
calloc (65536,
sizeof (rest_prefixes[0]));
226 if (!rest_prefixes) {
240 = (opc_table[prefix_insn] !=
NULL
241 ? opc_table[prefix_insn]
252 int offset = (prefix_insn & 255);
261 prefix_opc_table = bdapq_m4_prefixes;
265 prefix_opc_table = bdapq_m2_prefixes;
269 prefix_opc_table = bdapq_m1_prefixes;
273 prefix_opc_table = rest_prefixes;
279 prefix_opc_table = dip_prefixes;
281 prefix_opc_table = rest_prefixes;
286 max_matchedp = prefix_opc_table[insn];
288 max_matchedp = opc_table[insn];
291 int max_level_of_match = -1;
354 max_matchedp = opcodep;
355 max_level_of_match = level_of_match;
359 if (level_of_match >= 2 * 16) {
372 opc_table[insn] = max_matchedp;
374 prefix_opc_table[insn] = max_matchedp;
388 unsigned int prefix_insn,
396 for (
s =
cs; *
s;
s++) {
415 tmp = ((insn >> 12) & 0xf);
422 if ((insn & 0x30) == 0x30) {
465 int pushsize = (prefix_insn & 255);
467 if (pushsize > 127) {
472 unsigned int spec_reg = (insn >> 12) & 15;
477 if (sregp && sregp->
reg_size == (
unsigned int)-pushsize) {
480 }
else if (
s[1] ==
'R') {
481 if ((insn & 0x30) == 0x20 && pushsize == -4) {
492 retval = (((insn >> 12) & 15) == (insn & 15));
549 return outbuffer + strlen (outbuffer);
562 return outbuffer + strlen (outbuffer);
570 char *outbuffer_start,
573 char *outbuffer = outbuffer_start;
575 if (with_reg_prefix) {
584 strcpy (outbuffer,
"acr");
586 strcpy (outbuffer,
"pc");
591 strcpy (outbuffer,
"sp");
595 sprintf (outbuffer,
"r%d", regno);
599 return outbuffer_start + strlen (outbuffer_start);
606 char *outbuffer_start,
609 char *outbuffer = outbuffer_start;
612 if (with_reg_prefix) {
619 return outbuffer_start + strlen (outbuffer_start);
625 sprintf (outbuffer,
"format_sup_reg-BUG");
626 return outbuffer_start + strlen (outbuffer_start);
638 unsigned to_skip = 2;
639 const char *
template = matchedp->
args;
642 for (
s =
template; *
s;
s++) {
643 if ((*
s ==
's' || *
s ==
'N' || *
s ==
'Y') && (insn & 0x400) && (insn & 15) == 15 && !prefix_matchedp) {
646 int mode_size = 1 << ((insn >> 4) & (*
template ==
'z' ? 1 : 3));
665 to_skip += (mode_size + 1) & ~1;
667 }
else if (*
s ==
'n') {
669 }
else if (*
s ==
'b') {
687 static const char v8_fnames[] =
"cvznxibm";
688 static const char v32_fnames[] =
"cvznxiup";
692 unsigned char flagbits = (((insn >> 8) & 0xf0) | (insn & 15));
695 for (
i = 0;
i < 8;
i++) {
696 if (flagbits & (1 <<
i)) {
718 unsigned int prefix_insn,
719 unsigned char *prefix_buffer,
724 char temp[
sizeof (
".d [$r13=$r12-2147483648],$r10") * 2];
726 static const char mode_char[] =
"bwd?";
733 (*
info->fprintf_func) (
info->stream,
"%s", opcodep->
name);
743 if (*
s ==
'm' || *
s ==
'M' || *
s ==
'z')
749 ? (insn & 0x8000 ?
'd'
750 : insn & 0x4000 ?
'w' :
'b')
751 : mode_char[(insn >> 4) & (*
s ==
'z' ? 1 : 3)];
765 if (opcodep->
name[0] ==
'j') {
788 if (with_reg_prefix) {
818 prefix_opcodep =
NULL;
823 tp =
format_reg (disdata, insn & 15, tp, with_reg_prefix);
826 tp =
format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
832 unsigned long long number
839 (*
info->fprintf_func) (
info->stream,
"%s", temp);
850 unsigned long number = (
buffer[0] & 0xf) * 2 +
addr;
855 (*
info->fprintf_func) (
info->stream,
"%s", temp);
869 if ((insn & 0x400) && (insn & 15) == 15 && !prefix_opcodep)
875 = ((*
cs ==
'z' && (insn & 0x20))
901 int mode_size = 1 << ((insn >> 4) & (*
cs ==
'z' ? 1 : 3));
903 if (mode_size == 1) {
914 if (signedp &&
number > 127) {
921 if (signedp &&
number > 32767) {
941 unsigned int highbyte = (
number >> 24) & 0xff;
953 (*
info->fprintf_func) (
info->stream,
"%s", temp);
972 & (opcodep->
args[0] ==
'z' ? 1 : 3));
1001 && ((insn & 0x400) == 0
1006 tp =
format_reg (disdata, insn & 15, tp, with_reg_prefix);
1013 switch (prefix_opcodep->
match)
1017 if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
1022 = prefix_buffer[2] + prefix_buffer[3] * 256
1023 + prefix_buffer[4] * 65536
1024 + prefix_buffer[5] * 0x1000000;
1033 (*
info->fprintf_func) (
info->stream,
"%s", temp);
1046 info->target2 = prefix_insn & 15;
1049 tp =
format_reg (disdata, prefix_insn & 15, tp,
1051 if (prefix_insn & 0x400) {
1062 number = prefix_buffer[0];
1068 tp =
format_reg (disdata, (prefix_insn >> 12) & 15, tp,
1076 info->target = (prefix_insn >> 12) & 15;
1083 tp =
format_reg (disdata, prefix_insn & 15, tp,
1086 tp =
format_reg (disdata, (prefix_insn >> 12) & 15, tp,
1089 *tp++ = mode_char[(prefix_insn >> 4) & 3];
1095 | ((prefix_insn & 0x8000)
1097 : ((prefix_insn & 0x8000)
1101 if (insn == 0xf83f && (prefix_insn & ~0xf000) == 0x55f) {
1110 tp =
format_reg (disdata, (prefix_insn >> 12) & 15, tp,
1113 if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
1119 int mode_size = 1 << ((prefix_insn >> 4) & 3);
1121 if (mode_size == 1) {
1130 number = prefix_buffer[2];
1137 number = prefix_buffer[2] + prefix_buffer[3] * 256;
1145 = prefix_buffer[2] + prefix_buffer[3] * 256
1146 + prefix_buffer[4] * 65536
1147 + prefix_buffer[5] * 0x1000000;
1168 (*
info->fprintf_func) (
info->stream,
"%s", temp);
1185 tp =
format_reg (disdata, prefix_insn & 15, tp,
1187 if (prefix_insn & 0x400) {
1192 *tp++ = mode_char[(prefix_insn >> 4) & 3];
1199 | (((prefix_insn >> 4) == 2)
1201 : (((prefix_insn >> 4) & 3) == 1
1208 (*
info->fprintf_func) (
info->stream,
"?prefix-bug");
1212 prefix_opcodep =
NULL;
1216 tp =
format_reg (disdata, insn & 15, tp, with_reg_prefix);
1219 info->target = insn & 15;
1230 tp =
format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
1232 *tp++ = mode_char[(insn >> 4) & 3];
1243 if (where > 32767) {
1259 (*
info->fprintf_func) (
info->stream,
"%s%s ",
1276 long offset = insn & 0xfe;
1290 info->target = target;
1293 (*
info->fprintf_func) (
info->stream,
"%s", temp);
1294 (*
info->print_address_func) (target,
info);
1309 tp =
format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
1318 tp =
format_dec ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
1331 if (with_reg_prefix) {
1334 strcpy (tp, sregp->
name);
1349 if (prefix_opcodep) {
1350 (*
info->fprintf_func) (
info->stream,
" (OOPS unused prefix \"%s: %s\")",
1351 prefix_opcodep->
name, prefix_opcodep->
args);
1354 (*
info->fprintf_func) (
info->stream,
"%s", temp);
1401 unsigned char *bufp;
1430 info->insn_info_valid = 1;
1431 info->branch_delay_insns = 0;
1432 info->data_size = 0;
1442 insn = bufp[0] + bufp[1] * 256;
1450 (*
info->fprintf_func) (
info->stream,
"case %ld%s: -> ",
1462 }
else if (insn == 0) {
1467 (*
info->fprintf_func) (
info->stream,
1475 unsigned char *prefix_buffer = bufp;
1476 unsigned int prefix_insn = insn;
1477 int prefix_size = 0;
1488 prefix_opcodep = matchedp;
1490 insn = bufp[prefix_size] + bufp[prefix_size + 1] * 256;
1493 if (matchedp !=
NULL) {
1494 addr += prefix_size;
1495 bufp += prefix_size;
1496 advance += prefix_size;
1501 matchedp = prefix_opcodep;
1503 prefix_opcodep =
NULL;
1508 (*
info->fprintf_func) (
info->stream,
"??0x%x", insn);
1519 prefix_opcodep, prefix_insn,
1520 prefix_buffer, with_reg_prefix);
1542 info->bytes_per_chunk = 2;
1633 #define CR16_SUPPORTS_CPU 0
1637 #if CR16_SUPPORTS_CPU
RzBinInfo * info(RzBinFile *bf)
int bits(struct state *s, int need)
static char * format_dec(long number, char *outbuffer, int signedp)
#define REGISTER_PREFIX_CHAR
int print_insn_cris_without_register_prefix(bfd_vma vma, disassemble_info *info)
int print_insn_crisv32_without_register_prefix(bfd_vma vma, disassemble_info *info)
int print_insn_cris_with_register_prefix(bfd_vma vma, disassemble_info *info)
int print_insn_crisv32_with_register_prefix(bfd_vma vma, disassemble_info *info)
int print_insn_crisv10_v32_with_register_prefix(bfd_vma vma, disassemble_info *info)
static char * format_sup_reg(unsigned int regno, char *outbuffer_start, bfd_boolean with_reg_prefix)
static long case_offset_counter
static char * print_flags(struct cris_disasm_data *disdata, unsigned int insn, char *cp)
#define MAX_BYTES_PER_CRIS_INSN
static long no_of_case_offsets
bfd_boolean cris_parse_disassembler_options(disassemble_info *info, enum cris_disass_family distype)
static long last_immediate
static char * format_hex(unsigned long number, char *outbuffer, struct cris_disasm_data *disdata)
@ cris_dis_common_v10_v32
static void print_with_operands(const struct cris_opcode *opcodep, unsigned int insn, unsigned char *buffer, bfd_vma addr, disassemble_info *info, const struct cris_opcode *prefix_opcodep, unsigned int prefix_insn, unsigned char *prefix_buffer, bfd_boolean with_reg_prefix)
static int cris_constraint(const char *, unsigned, unsigned, struct cris_disasm_data *)
static int number_of_bits(unsigned int val)
static char * format_reg(struct cris_disasm_data *disdata, int regno, char *outbuffer_start, bfd_boolean with_reg_prefix)
static const struct cris_spec_reg * spec_reg_info(unsigned int sreg, enum cris_disass_family distype)
static unsigned bytes_to_skip(unsigned int insn, const struct cris_opcode *matchedp, enum cris_disass_family distype, const struct cris_opcode *prefix_matchedp)
int print_insn_crisv10_v32_without_register_prefix(bfd_vma vma, disassemble_info *info)
static const struct cris_opcode * get_opcode_entry(unsigned int insn, unsigned int prefix_insn, struct cris_disasm_data *disdata)
disassembler_ftype cris_get_disassembler(bfd *abfd)
int print_insn_cris_generic(bfd_vma memaddr, disassemble_info *info, bfd_boolean with_reg_prefix)
const char *const cris_cc_strings[]
const struct cris_support_reg cris_support_regs[]
const struct cris_spec_reg cris_spec_regs[]
const struct cris_opcode cris_opcodes[]
#define BDAP_INDIR_OPCODE
#define CRIS_DIS_FLAG_MEM_TARGET2_MEM_WORD
#define BA_PC_INCR_OPCODE
#define CRIS_DIS_FLAG_MEM_TARGET2_MULT2
#define BDAP_QUICK_OPCODE
#define CRIS_DIS_FLAG_MEM_TARGET2_MEM
#define CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
#define CRIS_DIS_FLAG_MEM_TARGET_IS_REG
#define CRIS_DIS_FLAG_MEM_TARGET2_MULT4
#define CRIS_DIS_FLAG_MEMREF
#define CRIS_DIS_FLAG_MEM_TARGET2_MEM_BYTE
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void nbytes
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags long
int(* disassembler_ftype)(bfd_vma, disassemble_info *)
return memset(p, 0, total)
void * calloc(size_t number, size_t size)
static const char struct stat static buf struct stat static buf static vhangup int status
#define CONST_STRNEQ(STR1, STR2)
BFD_HOST_U_64_BIT bfd_vma
#define bfd_get_symbol_leading_char(abfd)
enum cris_disass_family distype
enum cris_imm_oprnd_size_type imm_oprnd_size
enum cris_insn_version_usage applicable_version
enum cris_insn_version_usage applicable_version
const char *const warning
if(dbg->bits==RZ_SYS_BITS_64)