Rizin
unix-like reverse engineering framework and cli tools
cris-dis.c File Reference
#include <stdlib.h>
#include <string.h>
#include "disas-asm.h"
#include "sysdep.h"
#include "opcode/cris.h"
#include "libiberty.h"

Go to the source code of this file.

Classes

struct  cris_disasm_data
 

Macros

#define MAX_BYTES_PER_CRIS_INSN   8
 
#define PARSE_PREFIX   1
 
#define REGISTER_PREFIX_CHAR   '$'
 
#define TRACE_CASE   (disdata->trace_case)
 
#define CR16_SUPPORTS_CPU   0
 

Enumerations

enum  cris_disass_family { cris_dis_v0_v10 , cris_dis_common_v10_v32 , cris_dis_v32 }
 

Functions

static int cris_constraint (const char *, unsigned, unsigned, struct cris_disasm_data *)
 
bfd_boolean cris_parse_disassembler_options (disassemble_info *info, enum cris_disass_family distype)
 
static const struct cris_spec_regspec_reg_info (unsigned int sreg, enum cris_disass_family distype)
 
static int number_of_bits (unsigned int val)
 
static const struct cris_opcodeget_opcode_entry (unsigned int insn, unsigned int prefix_insn, struct cris_disasm_data *disdata)
 
static int cris_constraint (const char *cs, unsigned int insn, unsigned int prefix_insn, struct cris_disasm_data *disdata)
 
static char * format_hex (unsigned long number, char *outbuffer, struct cris_disasm_data *disdata)
 
static char * format_dec (long number, char *outbuffer, int signedp)
 
static char * format_reg (struct cris_disasm_data *disdata, int regno, char *outbuffer_start, bfd_boolean with_reg_prefix)
 
static char * format_sup_reg (unsigned int regno, char *outbuffer_start, bfd_boolean with_reg_prefix)
 
static unsigned bytes_to_skip (unsigned int insn, const struct cris_opcode *matchedp, enum cris_disass_family distype, const struct cris_opcode *prefix_matchedp)
 
static char * print_flags (struct cris_disasm_data *disdata, unsigned int insn, char *cp)
 
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)
 
int print_insn_cris_generic (bfd_vma memaddr, disassemble_info *info, bfd_boolean with_reg_prefix)
 
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)
 
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_crisv10_v32_without_register_prefix (bfd_vma vma, disassemble_info *info)
 
disassembler_ftype cris_get_disassembler (bfd *abfd)
 

Variables

static long case_offset = 0
 
static long case_offset_counter = 0
 
static long no_of_case_offsets = 0
 
static long last_immediate = 0
 

Macro Definition Documentation

◆ CR16_SUPPORTS_CPU

#define CR16_SUPPORTS_CPU   0

Definition at line 1633 of file cris-dis.c.

◆ MAX_BYTES_PER_CRIS_INSN

#define MAX_BYTES_PER_CRIS_INSN   8

Definition at line 35 of file cris-dis.c.

◆ PARSE_PREFIX

#define PARSE_PREFIX   1

Definition at line 41 of file cris-dis.c.

◆ REGISTER_PREFIX_CHAR

#define REGISTER_PREFIX_CHAR   '$'

Definition at line 45 of file cris-dis.c.

◆ TRACE_CASE

#define TRACE_CASE   (disdata->trace_case)

Definition at line 69 of file cris-dis.c.

Enumeration Type Documentation

◆ cris_disass_family

Enumerator
cris_dis_v0_v10 
cris_dis_common_v10_v32 
cris_dis_v32 

Definition at line 72 of file cris-dis.c.

@ cris_dis_v0_v10
Definition: cris-dis.c:73
@ cris_dis_common_v10_v32
Definition: cris-dis.c:73
@ cris_dis_v32
Definition: cris-dis.c:73

Function Documentation

◆ bytes_to_skip()

static unsigned bytes_to_skip ( unsigned int  insn,
const struct cris_opcode matchedp,
enum cris_disass_family  distype,
const struct cris_opcode prefix_matchedp 
)
static

Definition at line 632 of file cris-dis.c.

636 {
637  /* Each insn is a word plus "immediate" operands. */
638  unsigned to_skip = 2;
639  const char *template = matchedp->args;
640  const char *s;
641 
642  for (s = template; *s; s++) {
643  if ((*s == 's' || *s == 'N' || *s == 'Y') && (insn & 0x400) && (insn & 15) == 15 && !prefix_matchedp) {
644  /* Immediate via [pc+], so we have to check the size of the
645  operand. */
646  int mode_size = 1 << ((insn >> 4) & (*template == 'z' ? 1 : 3));
647 
648  if (matchedp->imm_oprnd_size == SIZE_FIX_32) {
649  to_skip += 4;
650  } else if (matchedp->imm_oprnd_size == SIZE_SPEC_REG) {
651  const struct cris_spec_reg *sregp = spec_reg_info ((insn >> 12) & 15, distype);
652 
653  /* FIXME: Improve error handling; should have been caught
654  earlier. */
655  if (!sregp) {
656  return 2;
657  }
658 
659  /* PC is incremented by two, not one, for a byte. Except on
660  CRISv32, where constants are always DWORD-size for
661  special registers. */
662  to_skip +=
663  distype == cris_dis_v32 ? 4 : (sregp->reg_size + 1) & ~1;
664  } else {
665  to_skip += (mode_size + 1) & ~1;
666  }
667  } else if (*s == 'n') {
668  to_skip += 4;
669  } else if (*s == 'b') {
670  to_skip += 2;
671  }
672  }
673 
674  return to_skip;
675 }
static const struct cris_spec_reg * spec_reg_info(unsigned int sreg, enum cris_disass_family distype)
Definition: cris-dis.c:126
@ SIZE_SPEC_REG
Definition: cris.h:235
@ SIZE_FIX_32
Definition: cris.h:232
static RzSocket * s
Definition: rtr.c:28
enum cris_imm_oprnd_size_type imm_oprnd_size
Definition: cris.h:306
const char * args
Definition: cris.h:300
unsigned int reg_size
Definition: cris.h:90

References cris_opcode::args, cris_dis_v32, cris_opcode::imm_oprnd_size, cris_spec_reg::reg_size, s, SIZE_FIX_32, SIZE_SPEC_REG, and spec_reg_info().

Referenced by print_insn_cris_generic().

◆ cris_constraint() [1/2]

static int cris_constraint ( const char *  ,
unsigned  ,
unsigned  ,
struct cris_disasm_data  
)
static

Referenced by get_opcode_entry().

◆ cris_constraint() [2/2]

static int cris_constraint ( const char *  cs,
unsigned int  insn,
unsigned int  prefix_insn,
struct cris_disasm_data disdata 
)
static

Definition at line 386 of file cris-dis.c.

390 {
391  int retval = 0;
392  int tmp;
393  int prefix_ok = 0;
394  const char *s;
395 
396  for (s = cs; *s; s++) {
397  switch (*s) {
398  case '!':
399  /* Do not recognize "pop" if there's a prefix and then only for
400  v0..v10. */
401  if (prefix_insn != NO_CRIS_PREFIX || disdata->distype != cris_dis_v0_v10) {
402  return -1;
403  }
404  break;
405 
406  case 'U':
407  /* Not recognized at disassembly. */
408  return -1;
409 
410  case 'M':
411  /* Size modifier for "clear", i.e. special register 0, 4 or 8.
412  Check that it is one of them. Only special register 12 could
413  be mismatched, but checking for matches is more logical than
414  checking for mismatches when there are only a few cases. */
415  tmp = ((insn >> 12) & 0xf);
416  if (tmp != 0 && tmp != 4 && tmp != 8) {
417  return -1;
418  }
419  break;
420 
421  case 'm':
422  if ((insn & 0x30) == 0x30) {
423  return -1;
424  }
425  break;
426 
427  case 'S':
428  /* A prefix operand without side-effect. */
429  if (prefix_insn != NO_CRIS_PREFIX && (insn & 0x400) == 0) {
430  prefix_ok = 1;
431  break;
432  } else {
433  return -1;
434  }
435 
436  case 's':
437  case 'y':
438  case 'Y':
439  /* If this is a prefixed insn with postincrement (side-effect),
440  the prefix must not be DIP. */
441  if (prefix_insn != NO_CRIS_PREFIX) {
442  if (insn & 0x400) {
443  const struct cris_opcode *prefix_opcodep = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);
444 
445  if (prefix_opcodep->match == DIP_OPCODE) {
446  return -1;
447  }
448  }
449 
450  prefix_ok = 1;
451  }
452  break;
453 
454  case 'B':
455  /* If we don't fall through, then the prefix is ok. */
456  prefix_ok = 1;
457 
458  /* A "push" prefix. Check for valid "push" size.
459  In case of special register, it may be != 4. */
460  if (prefix_insn != NO_CRIS_PREFIX) {
461  /* Match the prefix insn to BDAPQ. */
462  const struct cris_opcode *prefix_opcodep = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);
463 
464  if (prefix_opcodep->match == BDAP_QUICK_OPCODE) {
465  int pushsize = (prefix_insn & 255);
466 
467  if (pushsize > 127) {
468  pushsize -= 256;
469  }
470 
471  if (s[1] == 'P') {
472  unsigned int spec_reg = (insn >> 12) & 15;
473  const struct cris_spec_reg *sregp = spec_reg_info (spec_reg, disdata->distype);
474 
475  /* For a special-register, the "prefix size" must
476  match the size of the register. */
477  if (sregp && sregp->reg_size == (unsigned int)-pushsize) {
478  break;
479  }
480  } else if (s[1] == 'R') {
481  if ((insn & 0x30) == 0x20 && pushsize == -4) {
482  break;
483  }
484  }
485  /* FIXME: Should abort here; next constraint letter
486  *must* be 'P' or 'R'. */
487  }
488  }
489  return -1;
490 
491  case 'D':
492  retval = (((insn >> 12) & 15) == (insn & 15));
493  if (!retval) {
494  return -1;
495  } else {
496  retval += 4;
497  }
498  break;
499 
500  case 'P': {
501  const struct cris_spec_reg *sregp = spec_reg_info ((insn >> 12) & 15, disdata->distype);
502 
503  /* Since we match four bits, we will give a value of 4-1 = 3
504  in a match. If there is a corresponding exact match of a
505  special register in another pattern, it will get a value of
506  4, which will be higher. This should be correct in that an
507  exact pattern would match better than a general pattern.
508 
509  Note that there is a reason for not returning zero; the
510  pattern for "clear" is partly matched in the bit-pattern
511  (the two lower bits must be zero), while the bit-pattern
512  for a move from a special register is matched in the
513  register constraint. */
514 
515  if (sregp != NULL) {
516  retval += 3;
517  break;
518  } else {
519  return -1;
520  }
521  }
522  }
523  }
524 
525  if (prefix_insn != NO_CRIS_PREFIX && !prefix_ok) {
526  return -1;
527  }
528 
529  return retval;
530 }
static const struct cris_opcode * get_opcode_entry(unsigned int insn, unsigned int prefix_insn, struct cris_disasm_data *disdata)
Definition: cris-dis.c:174
#define NULL
Definition: cris-opc.c:27
#define NO_CRIS_PREFIX
Definition: cris.h:143
#define DIP_OPCODE
Definition: cris.h:128
#define BDAP_QUICK_OPCODE
Definition: cris.h:122
enum cris_disass_family distype
Definition: cris-dis.c:84
unsigned int match
Definition: cris.h:294

References BDAP_QUICK_OPCODE, cris_dis_v0_v10, test_evm::cs, DIP_OPCODE, cris_disasm_data::distype, get_opcode_entry(), cris_opcode::match, NO_CRIS_PREFIX, NULL, cris_spec_reg::reg_size, s, spec_reg_info(), and autogen_x86imm::tmp.

◆ cris_get_disassembler()

disassembler_ftype cris_get_disassembler ( bfd abfd)

Definition at line 1635 of file cris-dis.c.

1636 {
1637 #if CR16_SUPPORTS_CPU
1638 const int mode = 0; // V32 by default
1639  /* If there's no bfd in sight, we return what is valid as input in all
1640  contexts if fed back to the assembler: disassembly *with* register
1641  prefix. Unfortunately this will be totally wrong for v32. */
1642 if (!abfd) {
1644 }
1645 
1646 if (bfd_get_symbol_leading_char (abfd) == 0) {
1647  switch (mode) {
1648  case 0: // V32
1650  case 1: // V10_V32
1652  default:
1653 
1654  /* We default to v10. This may be specifically specified in the
1655  bfd mach, but is also the default setting. */
1657  }
1658  }
1659 
1660 switch (mode) {
1661 case 0: // V32
1662  //if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
1664 case 1: // V10_V32
1665  //if (bfd_get_mach (abfd) == bfd_mach_cris_v10_v32)
1667 default:
1669 }
1670 #else
1672 #endif
1673 }
int print_insn_cris_without_register_prefix(bfd_vma vma, disassemble_info *info)
Definition: cris-dis.c:1594
int print_insn_crisv32_without_register_prefix(bfd_vma vma, disassemble_info *info)
Definition: cris-dis.c:1606
int print_insn_cris_with_register_prefix(bfd_vma vma, disassemble_info *info)
Definition: cris-dis.c:1557
int print_insn_crisv32_with_register_prefix(bfd_vma vma, disassemble_info *info)
Definition: cris-dis.c:1569
int print_insn_crisv10_v32_with_register_prefix(bfd_vma vma, disassemble_info *info)
Definition: cris-dis.c:1582
int print_insn_crisv10_v32_without_register_prefix(bfd_vma vma, disassemble_info *info)
Definition: cris-dis.c:1619
const char int mode
Definition: ioapi.h:137
#define bfd_get_symbol_leading_char(abfd)
Definition: mybfd.h:524

References bfd_get_symbol_leading_char, print_insn_cris_with_register_prefix(), print_insn_cris_without_register_prefix(), print_insn_crisv10_v32_with_register_prefix(), print_insn_crisv10_v32_without_register_prefix(), print_insn_crisv32_with_register_prefix(), and print_insn_crisv32_without_register_prefix().

◆ cris_parse_disassembler_options()

bfd_boolean cris_parse_disassembler_options ( disassemble_info info,
enum cris_disass_family  distype 
)

Definition at line 106 of file cris-dis.c.

108 {
109  struct cris_disasm_data *disdata = (struct cris_disasm_data *) info->private_data;
110  if (!disdata) {
111  return FALSE;
112  }
113 
114  info->private_data = calloc (1, sizeof (struct cris_disasm_data));
115 
116  /* Default true. */
117  disdata->trace_case
118  = (!info->disassembler_options
119  || (strcmp (info->disassembler_options, "nocase") != 0));
120 
121  disdata->distype = distype;
122  return TRUE;
123 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define TRUE
Definition: mybfd.h:103
#define FALSE
Definition: mybfd.h:102
bfd_boolean trace_case
Definition: cris-dis.c:80
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References calloc(), cris_disasm_data::distype, FALSE, if(), info(), cris_disasm_data::trace_case, and TRUE.

Referenced by print_insn_cris_with_register_prefix(), print_insn_cris_without_register_prefix(), print_insn_crisv10_v32_with_register_prefix(), print_insn_crisv10_v32_without_register_prefix(), print_insn_crisv32_with_register_prefix(), and print_insn_crisv32_without_register_prefix().

◆ format_dec()

static char* format_dec ( long  number,
char *  outbuffer,
int  signedp 
)
static

Definition at line 557 of file cris-dis.c.

558 {
559  last_immediate = number;
560  sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
561 
562  return outbuffer + strlen (outbuffer);
563 }
static long last_immediate
Definition: cris-dis.c:97
sprintf
Definition: kernel.h:365

References last_immediate, cris_spec_reg::number, and sprintf.

Referenced by print_with_operands().

◆ format_hex()

static char* format_hex ( unsigned long  number,
char *  outbuffer,
struct cris_disasm_data disdata 
)
static

Definition at line 535 of file cris-dis.c.

538 {
539  /* Truncate negative numbers on >32-bit hosts. */
540  number &= 0xffffffff;
541 
542  sprintf (outbuffer, "0x%lx", number);
543 
544  /* Save this value for the "case" support. */
545  if (TRACE_CASE) {
546  last_immediate = number;
547  }
548 
549  return outbuffer + strlen (outbuffer);
550 }
#define TRACE_CASE
Definition: cris-dis.c:69

References last_immediate, cris_spec_reg::number, sprintf, and TRACE_CASE.

Referenced by print_with_operands().

◆ format_reg()

static char* format_reg ( struct cris_disasm_data disdata,
int  regno,
char *  outbuffer_start,
bfd_boolean  with_reg_prefix 
)
static

Definition at line 568 of file cris-dis.c.

572 {
573  char *outbuffer = outbuffer_start;
574 
575  if (with_reg_prefix) {
576  *outbuffer++ = REGISTER_PREFIX_CHAR;
577  }
578 
579  switch (regno)
580  {
581  case 15:
582  /* For v32, there is no context in which we output PC. */
583  if (disdata->distype == cris_dis_v32) {
584  strcpy (outbuffer, "acr");
585  } else {
586  strcpy (outbuffer, "pc");
587  }
588  break;
589 
590  case 14:
591  strcpy (outbuffer, "sp");
592  break;
593 
594  default:
595  sprintf (outbuffer, "r%d", regno);
596  break;
597  }
598 
599  return outbuffer_start + strlen (outbuffer_start);
600 }
#define REGISTER_PREFIX_CHAR
Definition: cris-dis.c:45

References cris_dis_v32, cris_disasm_data::distype, REGISTER_PREFIX_CHAR, and sprintf.

Referenced by print_with_operands().

◆ format_sup_reg()

static char* format_sup_reg ( unsigned int  regno,
char *  outbuffer_start,
bfd_boolean  with_reg_prefix 
)
static

Definition at line 605 of file cris-dis.c.

608 {
609  char *outbuffer = outbuffer_start;
610  int i;
611 
612  if (with_reg_prefix) {
613  *outbuffer++ = REGISTER_PREFIX_CHAR;
614  }
615 
616  for (i = 0; cris_support_regs[i].name != NULL; i++) {
617  if (cris_support_regs[i].number == regno) {
618  sprintf (outbuffer, "%s", cris_support_regs[i].name);
619  return outbuffer_start + strlen (outbuffer_start);
620  }
621  }
622 
623  /* There's supposed to be register names covering all numbers, though
624  some may be generic names. */
625  sprintf (outbuffer, "format_sup_reg-BUG");
626  return outbuffer_start + strlen (outbuffer_start);
627 }
lzma_index ** i
Definition: index.h:629
const struct cris_support_reg cris_support_regs[]
Definition: cris-opc.c:98
const char *const name
Definition: cris.h:104
Definition: z80asm.h:102

References cris_support_regs, i, cris_support_reg::name, NULL, cris_spec_reg::number, REGISTER_PREFIX_CHAR, and sprintf.

Referenced by print_with_operands().

◆ get_opcode_entry()

static const struct cris_opcode* get_opcode_entry ( unsigned int  insn,
unsigned int  prefix_insn,
struct cris_disasm_data disdata 
)
static

Definition at line 174 of file cris-dis.c.

177 {
178  /* For non-prefixed insns, we keep a table of pointers, indexed by the
179  insn code. Each entry is initialized when found to be NULL. */
180  static const struct cris_opcode **opc_table = NULL;
181 
182  const struct cris_opcode *max_matchedp = NULL;
183  const struct cris_opcode **prefix_opc_table = NULL;
184 
185  /* We hold a table for each prefix that need to be handled differently. */
186  static const struct cris_opcode **dip_prefixes = NULL;
187  static const struct cris_opcode **bdapq_m1_prefixes = NULL;
188  static const struct cris_opcode **bdapq_m2_prefixes = NULL;
189  static const struct cris_opcode **bdapq_m4_prefixes = NULL;
190  static const struct cris_opcode **rest_prefixes = NULL;
191 
192  /* Allocate and clear the opcode-table. */
193  if (!opc_table)
194  {
195  opc_table = calloc (65536, sizeof (opc_table[0]));
196  if (!opc_table) {
197  return NULL;
198  }
199 
200  dip_prefixes
201  = calloc (65536, sizeof (dip_prefixes[0]));
202  if (!dip_prefixes) {
203  return NULL;
204  }
205 
206  bdapq_m1_prefixes
207  = calloc (65536, sizeof (bdapq_m1_prefixes[0]));
208  if (!bdapq_m1_prefixes) {
209  return NULL;
210  }
211 
212  bdapq_m2_prefixes
213  = calloc (65536, sizeof (bdapq_m2_prefixes[0]));
214  if (!bdapq_m2_prefixes) {
215  return NULL;
216  }
217 
218  bdapq_m4_prefixes
219  = calloc (65536, sizeof (bdapq_m4_prefixes[0]));
220  if (!bdapq_m4_prefixes) {
221  return NULL;
222  }
223 
224  rest_prefixes
225  = calloc (65536, sizeof (rest_prefixes[0]));
226  if (!rest_prefixes) {
227  return NULL;
228  }
229  }
230 
231  /* Get the right table if this is a prefix.
232  This code is connected to cris_constraints in that it knows what
233  prefixes play a role in recognition of patterns; the necessary
234  state is reflected by which table is used. If constraints
235  involving match or non-match of prefix insns are changed, then this
236  probably needs changing too. */
237  if (prefix_insn != NO_CRIS_PREFIX)
238  {
239  const struct cris_opcode *popcodep
240  = (opc_table[prefix_insn] != NULL
241  ? opc_table[prefix_insn]
242  : get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata));
243 
244  if (!popcodep) {
245  return NULL;
246  }
247 
248  if (popcodep->match == BDAP_QUICK_OPCODE)
249  {
250  /* Since some offsets are recognized with "push" macros, we
251  have to have different tables for them. */
252  int offset = (prefix_insn & 255);
253 
254  if (offset > 127) {
255  offset -= 256;
256  }
257 
258  switch (offset)
259  {
260  case -4:
261  prefix_opc_table = bdapq_m4_prefixes;
262  break;
263 
264  case -2:
265  prefix_opc_table = bdapq_m2_prefixes;
266  break;
267 
268  case -1:
269  prefix_opc_table = bdapq_m1_prefixes;
270  break;
271 
272  default:
273  prefix_opc_table = rest_prefixes;
274  break;
275  }
276  } else if (popcodep->match == DIP_OPCODE) {
277  /* We don't allow postincrement when the prefix is DIP, so use a
278  different table for DIP. */
279  prefix_opc_table = dip_prefixes;
280  } else {
281  prefix_opc_table = rest_prefixes;
282  }
283  }
284 
285  if (prefix_insn != NO_CRIS_PREFIX && prefix_opc_table[insn] != NULL) {
286  max_matchedp = prefix_opc_table[insn];
287  } else if (prefix_insn == NO_CRIS_PREFIX && opc_table[insn] != NULL) {
288  max_matchedp = opc_table[insn];
289  } else {
290  const struct cris_opcode *opcodep;
291  int max_level_of_match = -1;
292 
293  for (opcodep = cris_opcodes;
294  opcodep->name != NULL;
295  opcodep++) {
296  int level_of_match;
297 
298  if (disdata->distype == cris_dis_v32) {
299  switch (opcodep->applicable_version) {
301  break;
302 
303  case cris_ver_v0_3:
304  case cris_ver_v0_10:
305  case cris_ver_v3_10:
306  case cris_ver_sim_v0_10:
307  case cris_ver_v8_10:
308  case cris_ver_v10:
309  case cris_ver_warning:
310  continue;
311 
312  case cris_ver_v3p:
313  case cris_ver_v8p:
314  case cris_ver_v10p:
315  case cris_ver_v32p:
316  break;
317 
318  case cris_ver_v8:
319  abort ();
320  default:
321  abort ();
322  }
323  } else {
324  switch (opcodep->applicable_version) {
326  case cris_ver_v0_3:
327  case cris_ver_v3p:
328  case cris_ver_v0_10:
329  case cris_ver_v8p:
330  case cris_ver_v8_10:
331  case cris_ver_v10:
332  case cris_ver_sim_v0_10:
333  case cris_ver_v10p:
334  case cris_ver_warning:
335  break;
336 
337  case cris_ver_v32p:
338  continue;
339 
340  case cris_ver_v8:
341  abort ();
342  default:
343  abort ();
344  }
345  }
346 
347  /* We give a double lead for bits matching the template in
348  cris_opcodes. Not even, because then "move p8,r10" would
349  be given 2 bits lead over "clear.d r10". When there's a
350  tie, the first entry in the table wins. This is
351  deliberate, to avoid a more complicated recognition
352  formula. */
353  if ((opcodep->match & insn) == opcodep->match && (opcodep->lose & insn) == 0 && ((level_of_match = cris_constraint (opcodep->args, insn, prefix_insn, disdata)) >= 0) && ((level_of_match += 2 * number_of_bits (opcodep->match | opcodep->lose)) > max_level_of_match)) {
354  max_matchedp = opcodep;
355  max_level_of_match = level_of_match;
356 
357  /* If there was a full match, never mind looking
358  further. */
359  if (level_of_match >= 2 * 16) {
360  break;
361  }
362  }
363  }
364  /* Fill in the new entry.
365 
366  If there are changes to the opcode-table involving prefixes, and
367  disassembly then does not work correctly, try removing the
368  else-clause below that fills in the prefix-table. If that
369  helps, you need to change the prefix_opc_table setting above, or
370  something related. */
371  if (prefix_insn == NO_CRIS_PREFIX) {
372  opc_table[insn] = max_matchedp;
373  } else {
374  prefix_opc_table[insn] = max_matchedp;
375  }
376  }
377 
378  return max_matchedp;
379 }
static int cris_constraint(const char *, unsigned, unsigned, struct cris_disasm_data *)
static int number_of_bits(unsigned int val)
Definition: cris-dis.c:160
const struct cris_opcode cris_opcodes[]
Definition: cris-opc.c:195
@ cris_ver_v32p
Definition: cris.h:81
@ cris_ver_v8p
Definition: cris.h:58
@ cris_ver_warning
Definition: cris.h:46
@ cris_ver_v8
Definition: cris.h:55
@ cris_ver_version_all
Definition: cris.h:43
@ cris_ver_v10
Definition: cris.h:73
@ cris_ver_v8_10
Definition: cris.h:70
@ cris_ver_v10p
Definition: cris.h:76
@ cris_ver_v0_3
Definition: cris.h:49
@ cris_ver_sim_v0_10
Definition: cris.h:61
@ cris_ver_v0_10
Definition: cris.h:64
@ cris_ver_v3p
Definition: cris.h:52
@ cris_ver_v3_10
Definition: cris.h:67
voidpf uLong offset
Definition: ioapi.h:144
const char * name
Definition: cris.h:291
enum cris_insn_version_usage applicable_version
Definition: cris.h:309
unsigned int lose
Definition: cris.h:297

References cris_opcode::applicable_version, cris_opcode::args, BDAP_QUICK_OPCODE, calloc(), cris_constraint(), cris_dis_v32, cris_opcodes, cris_ver_sim_v0_10, cris_ver_v0_10, cris_ver_v0_3, cris_ver_v10, cris_ver_v10p, cris_ver_v32p, cris_ver_v3_10, cris_ver_v3p, cris_ver_v8, cris_ver_v8_10, cris_ver_v8p, cris_ver_version_all, cris_ver_warning, DIP_OPCODE, cris_disasm_data::distype, cris_opcode::lose, cris_opcode::match, cris_opcode::name, NO_CRIS_PREFIX, NULL, and number_of_bits().

Referenced by cris_constraint(), and print_insn_cris_generic().

◆ number_of_bits()

static int number_of_bits ( unsigned int  val)
static

Definition at line 160 of file cris-dis.c.

161 {
162  int bits;
163 
164  for (bits = 0; val != 0; val &= val - 1) {
165  bits++;
166  }
167 
168  return bits;
169 }
ut16 val
Definition: armass64_const.h:6
int bits(struct state *s, int need)
Definition: blast.c:72

References bits(), and val.

Referenced by get_opcode_entry().

◆ print_flags()

static char* print_flags ( struct cris_disasm_data disdata,
unsigned int  insn,
char *  cp 
)
static

Definition at line 680 of file cris-dis.c.

681 {
682  /* Use the v8 (Etrax 100) flag definitions for disassembly.
683  The differences with v0 (Etrax 1..4) vs. Svinto are:
684  v0 'd' <=> v8 'm'
685  v0 'e' <=> v8 'b'.
686  FIXME: Emit v0..v3 flag names somehow. */
687  static const char v8_fnames[] = "cvznxibm";
688  static const char v32_fnames[] = "cvznxiup";
689  const char *fnames
690  = disdata->distype == cris_dis_v32 ? v32_fnames : v8_fnames;
691 
692  unsigned char flagbits = (((insn >> 8) & 0xf0) | (insn & 15));
693  int i;
694 
695  for (i = 0; i < 8; i++) {
696  if (flagbits & (1 << i)) {
697  *cp++ = fnames[i];
698  }
699  }
700 
701  return cp;
702 }

References cris_dis_v32, cris_disasm_data::distype, disasm_mc::fnames, and i.

Referenced by print_with_operands().

◆ print_insn_cris_generic()

int print_insn_cris_generic ( bfd_vma  memaddr,
disassemble_info info,
bfd_boolean  with_reg_prefix 
)

Definition at line 1387 of file cris-dis.c.

1390 {
1391  int nbytes;
1392  unsigned int insn;
1393  const struct cris_opcode *matchedp;
1394  int advance = 0;
1395  struct cris_disasm_data *disdata
1396  = (struct cris_disasm_data *) info->private_data;
1397 
1398  /* No instruction will be disassembled as longer than this number of
1399  bytes; stacked prefixes will not be expanded. */
1400  unsigned char buffer[MAX_BYTES_PER_CRIS_INSN];
1401  unsigned char *bufp;
1402  int status = 0;
1403  bfd_vma addr;
1404 
1405  /* There will be an "out of range" error after the last instruction.
1406  Reading pairs of bytes in decreasing number, we hope that we will get
1407  at least the amount that we will consume.
1408 
1409  If we can't get any data, or we do not get enough data, we print
1410  the error message. */
1411 
1412  for (nbytes = MAX_BYTES_PER_CRIS_INSN; nbytes > 0; nbytes -= 2)
1413  {
1414  status = (*info->read_memory_func) (memaddr, buffer, nbytes, info);
1415  if (status == 0) {
1416  break;
1417  }
1418  }
1419 
1420  /* If we did not get all we asked for, then clear the rest.
1421  Hopefully this makes a reproducible result in case of errors. */
1424  }
1425 
1426  addr = memaddr;
1427  bufp = buffer;
1428 
1429  /* Set some defaults for the insn info. */
1430  info->insn_info_valid = 1;
1431  info->branch_delay_insns = 0;
1432  info->data_size = 0;
1433  info->insn_type = dis_nonbranch;
1434  info->flags = 0;
1435  info->target = 0;
1436  info->target2 = 0;
1437 
1438  /* If we got any data, disassemble it. */
1439  if (nbytes != 0) {
1440  matchedp = NULL;
1441 
1442  insn = bufp[0] + bufp[1] * 256;
1443 
1444  /* If we're in a case-table, don't disassemble the offsets. */
1445  if (TRACE_CASE && case_offset_counter != 0) {
1446  info->insn_type = dis_noninsn;
1447  advance += 2;
1448 
1449  /* If to print data as offsets, then shortcut here. */
1450  (*info->fprintf_func) (info->stream, "case %ld%s: -> ",
1452  case_offset_counter == 1 ? "/default" : "");
1453 
1454  (*info->print_address_func) ((bfd_vma) ((short)(insn) + (long)(addr - (no_of_case_offsets - case_offset_counter) * 2)), info);
1456 
1457  /* The default case start (without a "sub" or "add") must be
1458  zero. */
1459  if (case_offset_counter == 0) {
1460  case_offset = 0;
1461  }
1462  } else if (insn == 0) {
1463  /* We're often called to disassemble zeroes. While this is a
1464  valid "bcc .+2" insn, it is also useless enough and enough
1465  of a nuiscance that we will just output "bcc .+2" for it
1466  and signal it as a noninsn. */
1467  (*info->fprintf_func) (info->stream,
1468  disdata->distype == cris_dis_v32
1469  ? "bcc ."
1470  : "bcc .+2");
1471  info->insn_type = dis_noninsn;
1472  advance += 2;
1473  } else {
1474  const struct cris_opcode *prefix_opcodep = NULL;
1475  unsigned char *prefix_buffer = bufp;
1476  unsigned int prefix_insn = insn;
1477  int prefix_size = 0;
1478 
1479  matchedp = get_opcode_entry (insn, NO_CRIS_PREFIX, disdata);
1480 
1481  /* Check if we're supposed to write out prefixes as address
1482  modes and if this was a prefix. */
1483  if (matchedp != NULL && PARSE_PREFIX && matchedp->args[0] == 'p') {
1484  /* If it's a prefix, put it into the prefix vars and get the
1485  main insn. */
1486  prefix_size = bytes_to_skip (prefix_insn, matchedp,
1487  disdata->distype, NULL);
1488  prefix_opcodep = matchedp;
1489 
1490  insn = bufp[prefix_size] + bufp[prefix_size + 1] * 256;
1491  matchedp = get_opcode_entry (insn, prefix_insn, disdata);
1492 
1493  if (matchedp != NULL) {
1494  addr += prefix_size;
1495  bufp += prefix_size;
1496  advance += prefix_size;
1497  } else {
1498  /* The "main" insn wasn't valid, at least not when
1499  prefixed. Put back things enough to output the
1500  prefix insn only, as a normal insn. */
1501  matchedp = prefix_opcodep;
1502  insn = prefix_insn;
1503  prefix_opcodep = NULL;
1504  }
1505  }
1506 
1507  if (!matchedp) {
1508  (*info->fprintf_func) (info->stream, "??0x%x", insn);
1509  advance += 2;
1510 
1511  info->insn_type = dis_noninsn;
1512  } else {
1513  advance += bytes_to_skip (insn, matchedp, disdata->distype,
1514  prefix_opcodep);
1515 
1516  /* The info_type and assorted fields will be set according
1517  to the operands. */
1518  print_with_operands (matchedp, insn, bufp, addr, info,
1519  prefix_opcodep, prefix_insn,
1520  prefix_buffer, with_reg_prefix);
1521  }
1522  }
1523  } else {
1524  info->insn_type = dis_noninsn;
1525  }
1526 
1527  /* If we read less than MAX_BYTES_PER_CRIS_INSN, i.e. we got an error
1528  status when reading that much, and the insn decoding indicated a
1529  length exceeding what we read, there is an error. */
1530  if (status != 0 && (nbytes == 0 || advance > nbytes)) {
1531  (*info->memory_error_func) (status, memaddr, info);
1532  return -1;
1533  }
1534 
1535  /* Max supported insn size with one folded prefix insn. */
1536  info->bytes_per_line = MAX_BYTES_PER_CRIS_INSN;
1537 
1538  /* I would like to set this to a fixed value larger than the actual
1539  number of bytes to print in order to avoid spaces between bytes,
1540  but objdump.c (2.9.1) does not like that, so we print 16-bit
1541  chunks, which is the next choice. */
1542  info->bytes_per_chunk = 2;
1543 
1544  /* Printing bytes in order of increasing addresses makes sense,
1545  especially on a little-endian target.
1546  This is completely the opposite of what you think; setting this to
1547  BFD_ENDIAN_LITTLE will print bytes in order N..0 rather than the 0..N
1548  we want. */
1549  info->display_endian = BFD_ENDIAN_BIG;
1550 
1551  return advance;
1552 }
struct buffer buffer
static long case_offset_counter
Definition: cris-dis.c:91
#define MAX_BYTES_PER_CRIS_INSN
Definition: cris-dis.c:35
static long no_of_case_offsets
Definition: cris-dis.c:94
static long case_offset
Definition: cris-dis.c:88
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)
Definition: cris-dis.c:709
#define PARSE_PREFIX
Definition: cris-dis.c:41
static unsigned bytes_to_skip(unsigned int insn, const struct cris_opcode *matchedp, enum cris_disass_family distype, const struct cris_opcode *prefix_matchedp)
Definition: cris-dis.c:632
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
Definition: sflib.h:113
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
Definition: sflib.h:79
@ dis_noninsn
Definition: disas-asm.h:48
@ dis_nonbranch
Definition: disas-asm.h:49
return memset(p, 0, total)
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
BFD_HOST_U_64_BIT bfd_vma
Definition: mybfd.h:111
@ BFD_ENDIAN_BIG
Definition: mybfd.h:4617
Definition: buffer.h:15
static int addr
Definition: z80asm.c:58

References addr, cris_opcode::args, BFD_ENDIAN_BIG, bytes_to_skip(), case_offset, case_offset_counter, cris_dis_v32, dis_nonbranch, dis_noninsn, cris_disasm_data::distype, get_opcode_entry(), info(), long, MAX_BYTES_PER_CRIS_INSN, memset(), nbytes, NO_CRIS_PREFIX, no_of_case_offsets, NULL, PARSE_PREFIX, print_with_operands(), status, and TRACE_CASE.

Referenced by print_insn_cris_with_register_prefix(), print_insn_cris_without_register_prefix(), print_insn_crisv10_v32_with_register_prefix(), print_insn_crisv10_v32_without_register_prefix(), print_insn_crisv32_with_register_prefix(), and print_insn_crisv32_without_register_prefix().

◆ print_insn_cris_with_register_prefix()

int print_insn_cris_with_register_prefix ( bfd_vma  vma,
disassemble_info info 
)

Definition at line 1557 of file cris-dis.c.

1559 {
1560  if (!info->private_data && !cris_parse_disassembler_options (info, cris_dis_v0_v10)) {
1561  return -1;
1562  }
1563  return print_insn_cris_generic (vma, info, TRUE);
1564 }
bfd_boolean cris_parse_disassembler_options(disassemble_info *info, enum cris_disass_family distype)
Definition: cris-dis.c:106
int print_insn_cris_generic(bfd_vma memaddr, disassemble_info *info, bfd_boolean with_reg_prefix)
Definition: cris-dis.c:1387

References cris_dis_v0_v10, cris_parse_disassembler_options(), info(), print_insn_cris_generic(), and TRUE.

Referenced by cris_get_disassembler(), and disassemble().

◆ print_insn_cris_without_register_prefix()

int print_insn_cris_without_register_prefix ( bfd_vma  vma,
disassemble_info info 
)

Definition at line 1594 of file cris-dis.c.

1596 {
1597  if (!info->private_data && !cris_parse_disassembler_options (info, cris_dis_v0_v10)) {
1598  return -1;
1599  }
1600  return print_insn_cris_generic (vma, info, FALSE);
1601 }

References cris_dis_v0_v10, cris_parse_disassembler_options(), FALSE, info(), and print_insn_cris_generic().

Referenced by cris_get_disassembler(), and disassemble().

◆ print_insn_crisv10_v32_with_register_prefix()

int print_insn_crisv10_v32_with_register_prefix ( bfd_vma  vma,
disassemble_info info 
)

Definition at line 1582 of file cris-dis.c.

1584 {
1586  return -1;
1587  }
1588  return print_insn_cris_generic (vma, info, TRUE);
1589 }

References cris_dis_common_v10_v32, cris_parse_disassembler_options(), info(), print_insn_cris_generic(), and TRUE.

Referenced by cris_get_disassembler(), and disassemble().

◆ print_insn_crisv10_v32_without_register_prefix()

int print_insn_crisv10_v32_without_register_prefix ( bfd_vma  vma,
disassemble_info info 
)

Definition at line 1619 of file cris-dis.c.

1621 {
1623  return -1;
1624  }
1625  return print_insn_cris_generic (vma, info, FALSE);
1626 }

References cris_dis_common_v10_v32, cris_parse_disassembler_options(), FALSE, info(), and print_insn_cris_generic().

Referenced by cris_get_disassembler(), and disassemble().

◆ print_insn_crisv32_with_register_prefix()

int print_insn_crisv32_with_register_prefix ( bfd_vma  vma,
disassemble_info info 
)

Definition at line 1569 of file cris-dis.c.

1571 {
1572  if (!info->private_data && !cris_parse_disassembler_options (info, cris_dis_v32)) {
1573  return -1;
1574  }
1575  return print_insn_cris_generic (vma, info, TRUE);
1576 }

References cris_dis_v32, cris_parse_disassembler_options(), info(), print_insn_cris_generic(), and TRUE.

Referenced by cris_get_disassembler(), and disassemble().

◆ print_insn_crisv32_without_register_prefix()

int print_insn_crisv32_without_register_prefix ( bfd_vma  vma,
disassemble_info info 
)

Definition at line 1606 of file cris-dis.c.

1608 {
1609  if (!info->private_data && !cris_parse_disassembler_options (info, cris_dis_v32)) {
1610  return -1;
1611  }
1612  return print_insn_cris_generic (vma, info, FALSE);
1613 }

References cris_dis_v32, cris_parse_disassembler_options(), FALSE, info(), and print_insn_cris_generic().

Referenced by cris_get_disassembler(), and disassemble().

◆ print_with_operands()

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

Definition at line 709 of file cris-dis.c.

721 {
722  /* Get a buffer of somewhat reasonable size where we store
723  intermediate parts of the insn. */
724  char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];
725  char *tp = temp;
726  static const char mode_char[] = "bwd?";
727  const char *s;
728  const char *cs;
729  struct cris_disasm_data *disdata
730  = (struct cris_disasm_data *) info->private_data;
731 
732  /* Print out the name first thing we do. */
733  (*info->fprintf_func) (info->stream, "%s", opcodep->name);
734 
735  cs = opcodep->args;
736  s = cs;
737 
738  /* Ignore any prefix indicator. */
739  if (*s == 'p') {
740  s++;
741  }
742 
743  if (*s == 'm' || *s == 'M' || *s == 'z')
744  {
745  *tp++ = '.';
746 
747  /* Get the size-letter. */
748  *tp++ = *s == 'M'
749  ? (insn & 0x8000 ? 'd'
750  : insn & 0x4000 ? 'w' : 'b')
751  : mode_char[(insn >> 4) & (*s == 'z' ? 1 : 3)];
752 
753  /* Ignore the size and the space character that follows. */
754  s += 2;
755  }
756 
757  /* Add a space if this isn't a long-branch, because for those will add
758  the condition part of the name later. */
759  if (opcodep->match != (BRANCH_PC_LOW + BRANCH_INCR_HIGH * 256)) {
760  *tp++ = ' ';
761  }
762 
763  /* Fill in the insn-type if deducible from the name (and there's no
764  better way). */
765  if (opcodep->name[0] == 'j') {
766  if (CONST_STRNEQ (opcodep->name, "jsr")) {
767  /* It's "jsr" or "jsrc". */
768  info->insn_type = dis_jsr;
769  } else {
770  /* Any other jump-type insn is considered a branch. */
771  info->insn_type = dis_branch;
772  }
773  }
774 
775  /* We might know some more fields right now. */
776  info->branch_delay_insns = opcodep->delayed;
777 
778  /* Handle operands. */
779  for (; *s; s++)
780  {
781  switch (*s)
782  {
783  case 'T':
784  tp = format_sup_reg ((insn >> 12) & 15, tp, with_reg_prefix);
785  break;
786 
787  case 'A':
788  if (with_reg_prefix) {
789  *tp++ = REGISTER_PREFIX_CHAR;
790  }
791  *tp++ = 'a';
792  *tp++ = 'c';
793  *tp++ = 'r';
794  break;
795 
796  case '[':
797  case ']':
798  case ',':
799  *tp++ = *s;
800  *tp++ = ' ';
801  break;
802 
803  case '!':
804  /* Ignore at this point; used at earlier stages to avoid
805  recognition if there's a prefix at something that in other
806  ways looks like a "pop". */
807  break;
808 
809  case 'd':
810  /* Ignore. This is an optional ".d " on the large one of
811  relaxable insns. */
812  break;
813 
814  case 'B':
815  /* This was the prefix that made this a "push". We've already
816  handled it by recognizing it, so signal that the prefix is
817  handled by setting it to NULL. */
818  prefix_opcodep = NULL;
819  break;
820 
821  case 'D':
822  case 'r':
823  tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
824  break;
825  case 'R':
826  tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
827  break;
828 
829  case 'n':
830  {
831  /* Like N but pc-relative to the start of the insn. */
832  unsigned long long number
833  = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536
834  + buffer[5] * 0x1000000 + addr);
835 
836  /* Finish off and output previous formatted bytes. */
837  *tp = 0;
838  if (temp[0]) {
839  (*info->fprintf_func) (info->stream, "%s", temp);
840  }
841  tp = temp;
842 
843  (*info->print_address_func) ((bfd_vma) number, info);
844  }
845  break;
846 
847  case 'u':
848  {
849  /* Like n but the offset is bits <3:0> in the instruction. */
850  unsigned long number = (buffer[0] & 0xf) * 2 + addr;
851 
852  /* Finish off and output previous formatted bytes. */
853  *tp = 0;
854  if (temp[0]) {
855  (*info->fprintf_func) (info->stream, "%s", temp);
856  }
857  tp = temp;
858 
859  (*info->print_address_func) ((bfd_vma) number, info);
860  }
861  break;
862 
863  case 'N':
864  case 'y':
865  case 'Y':
866  case 'S':
867  case 's':
868  /* Any "normal" memory operand. */
869  if ((insn & 0x400) && (insn & 15) == 15 && !prefix_opcodep)
870  {
871  /* We're looking at [pc+], i.e. we need to output an immediate
872  number, where the size can depend on different things. */
873  long number;
874  int signedp
875  = ((*cs == 'z' && (insn & 0x20))
876  || opcodep->match == BDAP_QUICK_OPCODE);
877  int nbytes;
878 
879  if (opcodep->imm_oprnd_size == SIZE_FIX_32) {
880  nbytes = 4;
881  } else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG) {
882  const struct cris_spec_reg *sregp = spec_reg_info ((insn >> 12) & 15, disdata->distype);
883 
884  /* A NULL return should have been as a non-match earlier,
885  so catch it as an internal error in the error-case
886  below. */
887  if (!sregp) {
888  /* Whatever non-valid size. */
889  nbytes = 42;
890  } else {
891  /* PC is always incremented by a multiple of two.
892  For CRISv32, immediates are always 4 bytes for
893  special registers. */
894  nbytes = disdata->distype == cris_dis_v32
895  ? 4
896  : (sregp->reg_size + 1) & ~1;
897  }
898  }
899  else
900  {
901  int mode_size = 1 << ((insn >> 4) & (*cs == 'z' ? 1 : 3));
902 
903  if (mode_size == 1) {
904  nbytes = 2;
905  } else {
906  nbytes = mode_size;
907  }
908  }
909 
910  switch (nbytes)
911  {
912  case 1:
913  number = buffer[2];
914  if (signedp && number > 127) {
915  number -= 256;
916  }
917  break;
918 
919  case 2:
920  number = buffer[2] + buffer[3] * 256;
921  if (signedp && number > 32767) {
922  number -= 65536;
923  }
924  break;
925 
926  case 4:
927  number
928  = buffer[2] + buffer[3] * 256 + buffer[4] * 65536
929  + buffer[5] * 0x1000000;
930  break;
931 
932  default:
933  strcpy (tp, "bug");
934  tp += 3;
935  number = 42;
936  }
937 
938  if ((*cs == 'z' && (insn & 0x20)) || (opcodep->match == BDAP_QUICK_OPCODE && (nbytes <= 2 || buffer[1 + nbytes] == 0))) {
939  tp = format_dec (number, tp, signedp);
940  } else {
941  unsigned int highbyte = (number >> 24) & 0xff;
942 
943  /* Either output this as an address or as a number. If it's
944  a dword with the same high-byte as the address of the
945  insn, assume it's an address, and also if it's a non-zero
946  non-0xff high-byte. If this is a jsr or a jump, then
947  it's definitely an address. */
948  if (nbytes == 4 && (highbyte == ((addr >> 24) & 0xff) || (highbyte != 0 && highbyte != 0xff) || info->insn_type == dis_branch || info->insn_type == dis_jsr)) {
949  /* Finish off and output previous formatted bytes. */
950  *tp = 0;
951  tp = temp;
952  if (temp[0]) {
953  (*info->fprintf_func) (info->stream, "%s", temp);
954  }
955 
956  (*info->print_address_func) ((bfd_vma)number, info);
957 
958  info->target = number;
959  } else {
960  tp = format_hex (number, tp, disdata);
961  }
962  }
963  }
964  else
965  {
966  /* Not an immediate number. Then this is a (possibly
967  prefixed) memory operand. */
968  if (info->insn_type != dis_nonbranch)
969  {
970  int mode_size
971  = 1 << ((insn >> 4)
972  & (opcodep->args[0] == 'z' ? 1 : 3));
973  int size;
974  info->insn_type = dis_dref;
975  info->flags |= CRIS_DIS_FLAG_MEMREF;
976 
977  if (opcodep->imm_oprnd_size == SIZE_FIX_32) {
978  size = 4;
979  } else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG) {
980  const struct cris_spec_reg *sregp = spec_reg_info ((insn >> 12) & 15, disdata->distype);
981 
982  /* FIXME: Improve error handling; should have been caught
983  earlier. */
984  if (!sregp) {
985  size = 4;
986  } else {
987  size = sregp->reg_size;
988  }
989  } else {
990  size = mode_size;
991  }
992 
993  info->data_size = size;
994  }
995 
996  *tp++ = '[';
997 
998  if (prefix_opcodep
999  /* We don't match dip with a postincremented field
1000  as a side-effect address mode. */
1001  && ((insn & 0x400) == 0
1002  || prefix_opcodep->match != DIP_OPCODE))
1003  {
1004  if (insn & 0x400)
1005  {
1006  tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
1007  *tp++ = '=';
1008  }
1009 
1010 
1011  /* We mainly ignore the prefix format string when the
1012  address-mode syntax is output. */
1013  switch (prefix_opcodep->match)
1014  {
1015  case DIP_OPCODE:
1016  /* It's [r], [r+] or [pc+]. */
1017  if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
1018  {
1019  /* It's [pc+]. This cannot possibly be anything
1020  but an address. */
1021  unsigned long number
1022  = prefix_buffer[2] + prefix_buffer[3] * 256
1023  + prefix_buffer[4] * 65536
1024  + prefix_buffer[5] * 0x1000000;
1025 
1026  info->target = (bfd_vma) number;
1027 
1028  /* Finish off and output previous formatted
1029  data. */
1030  *tp = 0;
1031  tp = temp;
1032  if (temp[0]) {
1033  (*info->fprintf_func) (info->stream, "%s", temp);
1034  }
1035 
1036  (*info->print_address_func) ((bfd_vma) number, info);
1037  }
1038  else
1039  {
1040  /* For a memref in an address, we use target2.
1041  In this case, target is zero. */
1042  info->flags
1045 
1046  info->target2 = prefix_insn & 15;
1047 
1048  *tp++ = '[';
1049  tp = format_reg (disdata, prefix_insn & 15, tp,
1050  with_reg_prefix);
1051  if (prefix_insn & 0x400) {
1052  *tp++ = '+';
1053  }
1054  *tp++ = ']';
1055  }
1056  break;
1057 
1058  case BDAP_QUICK_OPCODE:
1059  {
1060  int number;
1061 
1062  number = prefix_buffer[0];
1063  if (number > 127) {
1064  number -= 256;
1065  }
1066 
1067  /* Output "reg+num" or, if num < 0, "reg-num". */
1068  tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
1069  with_reg_prefix);
1070  if (number >= 0) {
1071  *tp++ = '+';
1072  }
1073  tp = format_dec (number, tp, 1);
1074 
1076  info->target = (prefix_insn >> 12) & 15;
1077  info->target2 = (bfd_vma) number;
1078  break;
1079  }
1080 
1081  case BIAP_OPCODE:
1082  /* Output "r+R.m". */
1083  tp = format_reg (disdata, prefix_insn & 15, tp,
1084  with_reg_prefix);
1085  *tp++ = '+';
1086  tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
1087  with_reg_prefix);
1088  *tp++ = '.';
1089  *tp++ = mode_char[(prefix_insn >> 4) & 3];
1090 
1091  info->flags
1094 
1095  | ((prefix_insn & 0x8000)
1097  : ((prefix_insn & 0x8000)
1099 
1100  /* Is it the casejump? It's a "adds.w [pc+r%d.w],pc". */
1101  if (insn == 0xf83f && (prefix_insn & ~0xf000) == 0x55f) {
1102  /* Then start interpreting data as offsets. */
1104  }
1105  break;
1106 
1107  case BDAP_INDIR_OPCODE:
1108  /* Output "r+s.m", or, if "s" is [pc+], "r+s" or
1109  "r-s". */
1110  tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
1111  with_reg_prefix);
1112 
1113  if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
1114  {
1115  long number;
1116  unsigned int nbytes;
1117 
1118  /* It's a value. Get its size. */
1119  int mode_size = 1 << ((prefix_insn >> 4) & 3);
1120 
1121  if (mode_size == 1) {
1122  nbytes = 2;
1123  } else {
1124  nbytes = mode_size;
1125  }
1126 
1127  switch (nbytes)
1128  {
1129  case 1:
1130  number = prefix_buffer[2];
1131  if (number > 127) {
1132  number -= 256;
1133  }
1134  break;
1135 
1136  case 2:
1137  number = prefix_buffer[2] + prefix_buffer[3] * 256;
1138  if (number > 32767) {
1139  number -= 65536;
1140  }
1141  break;
1142 
1143  case 4:
1144  number
1145  = prefix_buffer[2] + prefix_buffer[3] * 256
1146  + prefix_buffer[4] * 65536
1147  + prefix_buffer[5] * 0x1000000;
1148  break;
1149 
1150  default:
1151  strcpy (tp, "bug");
1152  tp += 3;
1153  number = 42;
1154  }
1155 
1157  info->target2 = (bfd_vma) number;
1158 
1159  /* If the size is dword, then assume it's an
1160  address. */
1161  if (nbytes == 4)
1162  {
1163  /* Finish off and output previous formatted
1164  bytes. */
1165  *tp++ = '+';
1166  *tp = 0;
1167  tp = temp;
1168  (*info->fprintf_func) (info->stream, "%s", temp);
1169 
1170  (*info->print_address_func) ((bfd_vma) number, info);
1171  }
1172  else
1173  {
1174  if (number >= 0) {
1175  *tp++ = '+';
1176  }
1177  tp = format_dec (number, tp, 1);
1178  }
1179  }
1180  else
1181  {
1182  /* Output "r+[R].m" or "r+[R+].m". */
1183  *tp++ = '+';
1184  *tp++ = '[';
1185  tp = format_reg (disdata, prefix_insn & 15, tp,
1186  with_reg_prefix);
1187  if (prefix_insn & 0x400) {
1188  *tp++ = '+';
1189  }
1190  *tp++ = ']';
1191  *tp++ = '.';
1192  *tp++ = mode_char[(prefix_insn >> 4) & 3];
1193 
1194  info->flags
1198 
1199  | (((prefix_insn >> 4) == 2)
1200  ? 0
1201  : (((prefix_insn >> 4) & 3) == 1
1204  }
1205  break;
1206 
1207  default:
1208  (*info->fprintf_func) (info->stream, "?prefix-bug");
1209  }
1210 
1211  /* To mark that the prefix is used, reset it. */
1212  prefix_opcodep = NULL;
1213  }
1214  else
1215  {
1216  tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
1217 
1219  info->target = insn & 15;
1220 
1221  if (insn & 0x400) {
1222  *tp++ = '+';
1223  }
1224  }
1225  *tp++ = ']';
1226  }
1227  break;
1228 
1229  case 'x':
1230  tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
1231  *tp++ = '.';
1232  *tp++ = mode_char[(insn >> 4) & 3];
1233  break;
1234 
1235  case 'I':
1236  tp = format_dec (insn & 63, tp, 0);
1237  break;
1238 
1239  case 'b':
1240  {
1241  int where = buffer[2] + buffer[3] * 256;
1242 
1243  if (where > 32767) {
1244  where -= 65536;
1245  }
1246 
1247  where += addr + ((disdata->distype == cris_dis_v32) ? 0 : 4);
1248 
1249  if (insn == BA_PC_INCR_OPCODE) {
1250  info->insn_type = dis_branch;
1251  } else {
1252  info->insn_type = dis_condbranch;
1253  }
1254 
1255  info->target = (bfd_vma) where;
1256 
1257  *tp = 0;
1258  tp = temp;
1259  (*info->fprintf_func) (info->stream, "%s%s ",
1260  temp, cris_cc_strings[insn >> 12]);
1261 
1262  (*info->print_address_func) ((bfd_vma) where, info);
1263  }
1264  break;
1265 
1266  case 'c':
1267  tp = format_dec (insn & 31, tp, 0);
1268  break;
1269 
1270  case 'C':
1271  tp = format_dec (insn & 15, tp, 0);
1272  break;
1273 
1274  case 'o':
1275  {
1276  long offset = insn & 0xfe;
1277  bfd_vma target;
1278 
1279  if (insn & 1) {
1280  offset |= ~0xff;
1281  }
1282 
1283  if (opcodep->match == BA_QUICK_OPCODE) {
1284  info->insn_type = dis_branch;
1285  } else {
1286  info->insn_type = dis_condbranch;
1287  }
1288 
1289  target = addr + ((disdata->distype == cris_dis_v32) ? 0 : 2) + offset;
1290  info->target = target;
1291  *tp = 0;
1292  tp = temp;
1293  (*info->fprintf_func) (info->stream, "%s", temp);
1294  (*info->print_address_func) (target, info);
1295  }
1296  break;
1297 
1298  case 'Q':
1299  case 'O':
1300  {
1301  long number = buffer[0];
1302 
1303  if (number > 127) {
1304  number = number - 256;
1305  }
1306 
1307  tp = format_dec (number, tp, 1);
1308  *tp++ = ',';
1309  tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
1310  }
1311  break;
1312 
1313  case 'f':
1314  tp = print_flags (disdata, insn, tp);
1315  break;
1316 
1317  case 'i':
1318  tp = format_dec ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
1319  break;
1320 
1321  case 'P':
1322  {
1323  const struct cris_spec_reg *sregp
1324  = spec_reg_info ((insn >> 12) & 15, disdata->distype);
1325 
1326 if (sregp) {
1327  if (!sregp->name) {
1328  /* Should have been caught as a non-match eariler. */
1329  *tp++ = '?';
1330  } else {
1331  if (with_reg_prefix) {
1332  *tp++ = REGISTER_PREFIX_CHAR;
1333  }
1334  strcpy (tp, sregp->name);
1335  tp += strlen (tp);
1336  }
1337 }
1338  }
1339  break;
1340 
1341  default:
1342  strcpy (tp, "???");
1343  tp += 3;
1344  }
1345  }
1346 
1347  *tp = 0;
1348 
1349  if (prefix_opcodep) {
1350  (*info->fprintf_func) (info->stream, " (OOPS unused prefix \"%s: %s\")",
1351  prefix_opcodep->name, prefix_opcodep->args);
1352  }
1353 
1354  (*info->fprintf_func) (info->stream, "%s", temp);
1355 
1356  /* Get info for matching case-tables, if we don't have any active.
1357  We assume that the last constant seen is used; either in the insn
1358  itself or in a "move.d const,rN, sub.d rN,rM"-like sequence. */
1359  if (TRACE_CASE && case_offset_counter == 0)
1360  {
1361  if (CONST_STRNEQ (opcodep->name, "sub")) {
1363 
1364  /* It could also be an "add", if there are negative case-values. */
1365  } else if (CONST_STRNEQ (opcodep->name, "add")) {
1366  /* The first case is the negated operand to the add. */
1368 
1369  /* A bound insn will tell us the number of cases. */
1370  } else if (CONST_STRNEQ (opcodep->name, "bound")) {
1372 
1373  /* A jump or jsr or branch breaks the chain of insns for a
1374  case-table, so assume default first-case again. */
1375  } else if (info->insn_type == dis_jsr || info->insn_type == dis_branch || info->insn_type == dis_condbranch) {
1376  case_offset = 0;
1377  }
1378  }
1379 }
static char * format_dec(long number, char *outbuffer, int signedp)
Definition: cris-dis.c:557
static char * format_sup_reg(unsigned int regno, char *outbuffer_start, bfd_boolean with_reg_prefix)
Definition: cris-dis.c:605
static char * print_flags(struct cris_disasm_data *disdata, unsigned int insn, char *cp)
Definition: cris-dis.c:680
static char * format_hex(unsigned long number, char *outbuffer, struct cris_disasm_data *disdata)
Definition: cris-dis.c:535
static char * format_reg(struct cris_disasm_data *disdata, int regno, char *outbuffer_start, bfd_boolean with_reg_prefix)
Definition: cris-dis.c:568
const char *const cris_cc_strings[]
Definition: cris-opc.c:1171
#define BDAP_INDIR_OPCODE
Definition: cris.h:136
#define CRIS_DIS_FLAG_MEM_TARGET2_MEM_WORD
Definition: cris.h:349
#define BA_QUICK_OPCODE
Definition: cris.h:177
#define BA_PC_INCR_OPCODE
Definition: cris.h:182
#define CRIS_DIS_FLAG_MEM_TARGET2_MULT2
Definition: cris.h:332
#define BIAP_OPCODE
Definition: cris.h:125
#define CRIS_DIS_FLAG_MEM_TARGET2_MEM
Definition: cris.h:341
#define CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
Definition: cris.h:328
#define BRANCH_PC_LOW
Definition: cris.h:180
#define CRIS_DIS_FLAG_MEM_TARGET_IS_REG
Definition: cris.h:325
#define CRIS_DIS_FLAG_MEM_TARGET2_MULT4
Definition: cris.h:336
#define CRIS_DIS_FLAG_MEMREF
Definition: cris.h:322
#define BRANCH_INCR_HIGH
Definition: cris.h:181
#define CRIS_DIS_FLAG_MEM_TARGET2_MEM_BYTE
Definition: cris.h:345
@ dis_dref
Definition: disas-asm.h:54
@ dis_condbranch
Definition: disas-asm.h:51
@ dis_jsr
Definition: disas-asm.h:52
@ dis_branch
Definition: disas-asm.h:50
voidpf void uLong size
Definition: ioapi.h:138
#define CONST_STRNEQ(STR1, STR2)
Definition: mybfd.h:5000
char delayed
Definition: cris.h:303
unsigned int number
Definition: cris.h:87
const char *const name
Definition: cris.h:86

References addr, cris_opcode::args, BA_PC_INCR_OPCODE, BA_QUICK_OPCODE, BDAP_INDIR_OPCODE, BDAP_QUICK_OPCODE, BIAP_OPCODE, BRANCH_INCR_HIGH, BRANCH_PC_LOW, case_offset, case_offset_counter, CONST_STRNEQ, cris_cc_strings, CRIS_DIS_FLAG_MEM_TARGET2_IS_REG, CRIS_DIS_FLAG_MEM_TARGET2_MEM, CRIS_DIS_FLAG_MEM_TARGET2_MEM_BYTE, CRIS_DIS_FLAG_MEM_TARGET2_MEM_WORD, CRIS_DIS_FLAG_MEM_TARGET2_MULT2, CRIS_DIS_FLAG_MEM_TARGET2_MULT4, CRIS_DIS_FLAG_MEM_TARGET_IS_REG, CRIS_DIS_FLAG_MEMREF, cris_dis_v32, test_evm::cs, cris_opcode::delayed, DIP_OPCODE, dis_branch, dis_condbranch, dis_dref, dis_jsr, dis_nonbranch, cris_disasm_data::distype, format_dec(), format_hex(), format_reg(), format_sup_reg(), cris_opcode::imm_oprnd_size, info(), last_immediate, cris_opcode::match, cris_spec_reg::name, cris_opcode::name, nbytes, no_of_case_offsets, NULL, cris_spec_reg::number, print_flags(), cris_spec_reg::reg_size, REGISTER_PREFIX_CHAR, s, SIZE_FIX_32, SIZE_SPEC_REG, spec_reg_info(), and TRACE_CASE.

Referenced by print_insn_cris_generic().

◆ spec_reg_info()

static const struct cris_spec_reg* spec_reg_info ( unsigned int  sreg,
enum cris_disass_family  distype 
)
static

Definition at line 126 of file cris-dis.c.

127 {
128  int i;
129 
130  for (i = 0; cris_spec_regs[i].name != NULL; i++)
131  {
132  if (cris_spec_regs[i].number == sreg)
133  {
134  if (distype == cris_dis_v32) {
135  switch (cris_spec_regs[i].applicable_version) {
136  case cris_ver_warning:
138  case cris_ver_v3p:
139  case cris_ver_v8p:
140  case cris_ver_v10p:
141  case cris_ver_v32p:
142  /* No ambiguous sizes or register names with CRISv32. */
143  if (!cris_spec_regs[i].warning) {
144  return &cris_spec_regs[i];
145  }
146  default:;
147  }
148  } else if (cris_spec_regs[i].applicable_version != cris_ver_v32p) {
149  return &cris_spec_regs[i];
150  }
151  }
152  }
153 
154  return NULL;
155 }
const struct cris_spec_reg cris_spec_regs[]
Definition: cris-opc.c:32

References cris_spec_reg::applicable_version, cris_dis_v32, cris_spec_regs, cris_ver_v10p, cris_ver_v32p, cris_ver_v3p, cris_ver_v8p, cris_ver_version_all, cris_ver_warning, i, cris_spec_reg::name, NULL, cris_spec_reg::number, and cris_spec_reg::warning.

Referenced by bytes_to_skip(), cris_constraint(), and print_with_operands().

Variable Documentation

◆ case_offset

long case_offset = 0
static

Definition at line 88 of file cris-dis.c.

Referenced by print_insn_cris_generic(), and print_with_operands().

◆ case_offset_counter

long case_offset_counter = 0
static

Definition at line 91 of file cris-dis.c.

Referenced by print_insn_cris_generic(), and print_with_operands().

◆ last_immediate

long last_immediate = 0
static

Definition at line 97 of file cris-dis.c.

Referenced by format_dec(), format_hex(), and print_with_operands().

◆ no_of_case_offsets

long no_of_case_offsets = 0
static

Definition at line 94 of file cris-dis.c.

Referenced by print_insn_cris_generic(), and print_with_operands().