Пример #1
0
int
print_insn_pj (bfd_vma addr, struct disassemble_info *info)
{
  fprintf_ftype fprintf_fn = info->fprintf_func;
  void *stream = info->stream;
  unsigned char opcode;
  int status;

  if ((status = info->read_memory_func (addr, &opcode, 1, info)))
    goto fail;

  if (opcode == 0xff)
    {
      unsigned char byte_2;

      if ((status = info->read_memory_func (addr + 1, &byte_2, 1, info)))
	goto fail;
      fprintf_fn (stream, "%s\t", pj_opc_info[opcode + byte_2].u.name);
      return 2;
    }
  else
    {
      char *sep = "\t";
      int insn_start = addr;
      const pj_opc_info_t *op = &pj_opc_info[opcode];
      int a;

      addr++;
      fprintf_fn (stream, "%s", op->u.name);

      /* The tableswitch instruction is followed by the default
	 address, low value, high value and the destinations.  */

      if (strcmp (op->u.name, "tableswitch") == 0)
	{
	  int lowval;
	  int highval;
	  int val;

	  addr = (addr + 3) & ~3;
	  if ((status = get_int (addr, &val, info)))
	    goto fail;

	  fprintf_fn (stream, " default: ");
	  (*info->print_address_func) (val + insn_start, info);
	  addr += 4;

	  if ((status = get_int (addr, &lowval, info)))
	    goto fail;
	  addr += 4;

	  if ((status = get_int (addr, &highval, info)))
	    goto fail;
	  addr += 4;

	  while (lowval <= highval)
	    {
	      if ((status = get_int (addr, &val, info)))
		goto fail;
	      fprintf_fn (stream, " %d:[", lowval);
	      (*info->print_address_func) (val + insn_start, info);
	      fprintf_fn (stream, " ]");
	      addr += 4;
	      lowval++;
	    }
	  return addr - insn_start;
	}

      /* The lookupswitch instruction is followed by the default
	 address, element count and pairs of values and
	 addresses.  */
      if (strcmp (op->u.name, "lookupswitch") == 0)
	{
	  int count;
	  int val;

	  addr = (addr + 3) & ~3;
	  if ((status = get_int (addr, &val, info)))
	    goto fail;
	  addr += 4;

	  fprintf_fn (stream, " default: ");
	  (*info->print_address_func) (val + insn_start, info);

	  if ((status = get_int (addr, &count, info)))
	    goto fail;
	  addr += 4;

	  while (count--)
	    {
	      if ((status = get_int (addr, &val, info)))
		goto fail;
	      addr += 4;
	      fprintf_fn (stream, " %d:[", val);

	      if ((status = get_int (addr, &val, info)))
		goto fail;
	      addr += 4;

	      (*info->print_address_func) (val + insn_start, info);
	      fprintf_fn (stream, " ]");
	    }
	  return addr - insn_start;
	}

      for (a = 0; op->arg[a]; a++)
	{
	  unsigned char data[4];
	  int val = 0;
	  int i;
	  int size = ASIZE (op->arg[a]);

	  if ((status = info->read_memory_func (addr, data, size, info)))
	    goto fail;

	  val = (UNS (op->arg[0]) || ((data[0] & 0x80) == 0)) ? 0 : -1;

	  for (i = 0; i < size; i++)
	    val = (val << 8) | (data[i] & 0xff);

	  if (PCREL (op->arg[a]))
	    (*info->print_address_func) (val + insn_start, info);
	  else
	    fprintf_fn (stream, "%s%d", sep, val);

	  sep = ",";
	  addr += size;
	}
      return op->len;
    }

 fail:
  info->memory_error_func (status, addr, info);
  return -1;
}
Пример #2
0
const struct mips_operand *
decode_mips16_operand (char type, bfd_boolean extended_p)
{
  switch (type)
    {
    case '0': MAPPED_REG (0, 0, GP, reg_0_map);

    case 'L': SPECIAL (6, 5, ENTRY_EXIT_LIST);
    case 'M': SPECIAL (7, 0, SAVE_RESTORE_LIST);
    case 'P': SPECIAL (0, 0, PC);
    case 'R': MAPPED_REG (0, 0, GP, reg_31_map);
    case 'S': MAPPED_REG (0, 0, GP, reg_29_map);
    case 'X': REG (5, 0, GP);
    case 'Y': MAPPED_REG (5, 3, GP, reg32r_map);
    case 'Z': MAPPED_REG (3, 0, GP, reg_m16_map);

    case 'a': JUMP (26, 0, 2);
    case 'e': UINT (11, 0);
    case 'i': JALX (26, 0, 2);
    case 'l': SPECIAL (6, 5, ENTRY_EXIT_LIST);
    case 'm': SPECIAL (7, 0, SAVE_RESTORE_LIST);
    case 'v': MAPPED_REG (3, 8, GP, reg_m16_map);
    case 'w': MAPPED_REG (3, 5, GP, reg_m16_map);
    case 'x': MAPPED_REG (3, 8, GP, reg_m16_map);
    case 'y': MAPPED_REG (3, 5, GP, reg_m16_map);
    case 'z': MAPPED_REG (3, 2, GP, reg_m16_map);
    }

  if (extended_p)
    switch (type)
      {
      case '<': UINT (5, 0);
      case '>': UINT (5, 0);
      case '[': UINT (6, 0);
      case ']': UINT (6, 0);

      case '4': SINT (15, 0);
      case '5': SINT (16, 0);
      case '6': SINT (16, 0);
      case '8': SINT (16, 0);

      case 'A': PCREL (16, 0, TRUE, 0, 2, FALSE, FALSE);
      case 'B': PCREL (16, 0, TRUE, 0, 3, FALSE, FALSE);
      case 'C': SINT (16, 0);
      case 'D': SINT (16, 0);
      case 'E': PCREL (16, 0, TRUE, 0, 2, FALSE, FALSE);
      case 'H': SINT (16, 0);
      case 'K': SINT (16, 0);
      case 'U': UINT (16, 0);
      case 'V': SINT (16, 0);
      case 'W': SINT (16, 0);

      case 'j': SINT (16, 0);
      case 'k': SINT (16, 0);
      case 'p': BRANCH (16, 0, 1);
      case 'q': BRANCH (16, 0, 1);
      }
  else
    switch (type)
      {
      case '<': INT_ADJ (3, 2, 8, 0, FALSE);
      case '>': INT_ADJ (3, 8, 8, 0, FALSE);
      case '[': INT_ADJ (3, 2, 8, 0, FALSE);
      case ']': INT_ADJ (3, 8, 8, 0, FALSE);

      case '4': SINT (4, 0);
      case '5': UINT (5, 0);
      case '6': UINT (6, 5);
      case '8': UINT (8, 0);

      case 'A': PCREL (8, 0, FALSE, 2, 2, FALSE, FALSE);
      case 'B': PCREL (5, 0, FALSE, 3, 3, FALSE, FALSE);
      case 'C': INT_ADJ (8, 0, 255, 3, FALSE);	/* (0 .. 255) << 3 */
      case 'D': INT_ADJ (5, 0, 31, 3, FALSE);	/* (0 .. 31) << 3 */
      case 'E': PCREL (5, 0, FALSE, 2, 2, FALSE, FALSE);
      case 'H': INT_ADJ (5, 0, 31, 1, FALSE);	/* (0 .. 31) << 1 */
      case 'K': INT_ADJ (8, 0, 127, 3, FALSE);	/* (-128 .. 127) << 3 */
      case 'U': UINT (8, 0);
      case 'V': INT_ADJ (8, 0, 255, 2, FALSE);	/* (0 .. 255) << 2 */
      case 'W': INT_ADJ (5, 0, 31, 2, FALSE);	/* (0 .. 31) << 2 */

      case 'j': SINT (5, 0);
      case 'k': SINT (8, 0);
      case 'p': BRANCH (8, 0, 1);
      case 'q': BRANCH (11, 0, 1);
      }
  return 0;
}
Пример #3
0
const struct mips_operand *
decode_mips16_operand (char type, bfd_boolean extended_p)
{
  switch (type)
    {
    case '.': MAPPED_REG (0, 0, GP, reg_0_map);
    case '>': HINT (5, 22);

    case '0': HINT (5, 0);
    case '1': HINT (3, 5);
    case '2': HINT (3, 8);
    case '3': HINT (5, 16);
    case '4': HINT (3, 21);
    case '6': HINT (6, 5);
    case '9': SINT (9, 0);

    case 'G': SPECIAL (0, 0, REG28);
    case 'L': SPECIAL (6, 5, ENTRY_EXIT_LIST);
    case 'N': REG (5, 0, COPRO);
    case 'O': UINT (3, 21);
    case 'Q': REG (5, 16, HW);
    case 'P': SPECIAL (0, 0, PC);
    case 'R': MAPPED_REG (0, 0, GP, reg_31_map);
    case 'S': MAPPED_REG (0, 0, GP, reg_29_map);
    case 'T': HINT (5, 16);
    case 'X': REG (5, 0, GP);
    case 'Y': MAPPED_REG (5, 3, GP, reg32r_map);
    case 'Z': MAPPED_REG (3, 0, GP, reg_m16_map);

    case 'a': JUMP (26, 0, 2);
    case 'b': BIT (5, 22, 0);			/* (0 .. 31) */
    case 'c': MSB (5, 16, 1, TRUE, 32);		/* (1 .. 32) */
    case 'd': MSB (5, 16, 1, FALSE, 32);	/* (1 .. 32) */
    case 'e': HINT (11, 0);
    case 'i': JALX (26, 0, 2);
    case 'l': SPECIAL (6, 5, ENTRY_EXIT_LIST);
    case 'm': SPECIAL (7, 0, SAVE_RESTORE_LIST);
    case 'n': INT_BIAS (2, 0, 3, 1, 0, FALSE);	/* (1 .. 4) */
    case 'o': INT_ADJ (5, 16, 31, 4, FALSE);	/* (0 .. 31) << 4 */
    case 'r': MAPPED_REG (3, 16, GP, reg_m16_map);
    case 's': HINT (3, 24);
    case 'u': HINT (16, 0);
    case 'v': OPTIONAL_MAPPED_REG (3, 8, GP, reg_m16_map);
    case 'w': OPTIONAL_MAPPED_REG (3, 5, GP, reg_m16_map);
    case 'x': MAPPED_REG (3, 8, GP, reg_m16_map);
    case 'y': MAPPED_REG (3, 5, GP, reg_m16_map);
    case 'z': MAPPED_REG (3, 2, GP, reg_m16_map);
    }

  if (extended_p)
    switch (type)
      {
      case '<': UINT (5, 22);
      case '[': UINT (6, 0);
      case ']': UINT (6, 0);

      case '5': SINT (16, 0);
      case '8': SINT (16, 0);

      case 'A': PCREL (16, 0, TRUE, 0, 2, FALSE, FALSE);
      case 'B': PCREL (16, 0, TRUE, 0, 3, FALSE, FALSE);
      case 'C': SINT (16, 0);
      case 'D': SINT (16, 0);
      case 'E': PCREL (16, 0, TRUE, 0, 2, FALSE, FALSE);
      case 'F': SINT (15, 0);
      case 'H': SINT (16, 0);
      case 'K': SINT (16, 0);
      case 'U': UINT (16, 0);
      case 'V': SINT (16, 0);
      case 'W': SINT (16, 0);

      case 'j': SINT (16, 0);
      case 'k': SINT (16, 0);
      case 'p': BRANCH (16, 0, 1);
      case 'q': BRANCH (16, 0, 1);
      }
  else
    switch (type)
      {
      case '<': INT_ADJ (3, 2, 8, 0, FALSE);
      case '[': INT_ADJ (3, 2, 8, 0, FALSE);
      case ']': INT_ADJ (3, 8, 8, 0, FALSE);

      case '5': UINT (5, 0);
      case '8': UINT (8, 0);

      case 'A': PCREL (8, 0, FALSE, 2, 2, FALSE, FALSE);
      case 'B': PCREL (5, 0, FALSE, 3, 3, FALSE, FALSE);
      case 'C': INT_ADJ (8, 0, 255, 3, FALSE);	/* (0 .. 255) << 3 */
      case 'D': INT_ADJ (5, 0, 31, 3, FALSE);	/* (0 .. 31) << 3 */
      case 'E': PCREL (5, 0, FALSE, 2, 2, FALSE, FALSE);
      case 'F': SINT (4, 0);
      case 'H': INT_ADJ (5, 0, 31, 1, FALSE);	/* (0 .. 31) << 1 */
      case 'K': INT_ADJ (8, 0, 127, 3, FALSE);	/* (-128 .. 127) << 3 */
      case 'U': UINT (8, 0);
      case 'V': INT_ADJ (8, 0, 255, 2, FALSE);	/* (0 .. 255) << 2 */
      case 'W': INT_ADJ (5, 0, 31, 2, FALSE);	/* (0 .. 31) << 2 */

      case 'j': SINT (5, 0);
      case 'k': SINT (8, 0);
      case 'p': BRANCH (8, 0, 1);
      case 'q': BRANCH (11, 0, 1);
      }
  return 0;
}