pj-dis.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* pj-dis.c -- Disassemble picoJava instructions.
  2. Copyright (C) 1999-2015 Free Software Foundation, Inc.
  3. Contributed by Steve Chamberlain, of Transmeta (sac@pobox.com).
  4. This file is part of the GNU opcodes library.
  5. This library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. It is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. #include "sysdep.h"
  18. #include <stdio.h>
  19. #include "opcode/pj.h"
  20. #include "dis-asm.h"
  21. extern const pj_opc_info_t pj_opc_info[512];
  22. static int
  23. get_int (bfd_vma memaddr, int *iptr, struct disassemble_info *info)
  24. {
  25. unsigned char ival[4];
  26. int status = info->read_memory_func (memaddr, ival, 4, info);
  27. *iptr = (ival[0] << 24)
  28. | (ival[1] << 16)
  29. | (ival[2] << 8)
  30. | (ival[3] << 0);
  31. return status;
  32. }
  33. int
  34. print_insn_pj (bfd_vma addr, struct disassemble_info *info)
  35. {
  36. fprintf_ftype fprintf_fn = info->fprintf_func;
  37. void *stream = info->stream;
  38. unsigned char opcode;
  39. int status;
  40. if ((status = info->read_memory_func (addr, &opcode, 1, info)))
  41. goto fail;
  42. if (opcode == 0xff)
  43. {
  44. unsigned char byte_2;
  45. if ((status = info->read_memory_func (addr + 1, &byte_2, 1, info)))
  46. goto fail;
  47. fprintf_fn (stream, "%s\t", pj_opc_info[opcode + byte_2].u.name);
  48. return 2;
  49. }
  50. else
  51. {
  52. char *sep = "\t";
  53. int insn_start = addr;
  54. const pj_opc_info_t *op = &pj_opc_info[opcode];
  55. int a;
  56. addr++;
  57. fprintf_fn (stream, "%s", op->u.name);
  58. /* The tableswitch instruction is followed by the default
  59. address, low value, high value and the destinations. */
  60. if (strcmp (op->u.name, "tableswitch") == 0)
  61. {
  62. int lowval;
  63. int highval;
  64. int val;
  65. addr = (addr + 3) & ~3;
  66. if ((status = get_int (addr, &val, info)))
  67. goto fail;
  68. fprintf_fn (stream, " default: ");
  69. (*info->print_address_func) (val + insn_start, info);
  70. addr += 4;
  71. if ((status = get_int (addr, &lowval, info)))
  72. goto fail;
  73. addr += 4;
  74. if ((status = get_int (addr, &highval, info)))
  75. goto fail;
  76. addr += 4;
  77. while (lowval <= highval)
  78. {
  79. if ((status = get_int (addr, &val, info)))
  80. goto fail;
  81. fprintf_fn (stream, " %d:[", lowval);
  82. (*info->print_address_func) (val + insn_start, info);
  83. fprintf_fn (stream, " ]");
  84. addr += 4;
  85. lowval++;
  86. }
  87. return addr - insn_start;
  88. }
  89. /* The lookupswitch instruction is followed by the default
  90. address, element count and pairs of values and
  91. addresses. */
  92. if (strcmp (op->u.name, "lookupswitch") == 0)
  93. {
  94. int count;
  95. int val;
  96. addr = (addr + 3) & ~3;
  97. if ((status = get_int (addr, &val, info)))
  98. goto fail;
  99. addr += 4;
  100. fprintf_fn (stream, " default: ");
  101. (*info->print_address_func) (val + insn_start, info);
  102. if ((status = get_int (addr, &count, info)))
  103. goto fail;
  104. addr += 4;
  105. while (count--)
  106. {
  107. if ((status = get_int (addr, &val, info)))
  108. goto fail;
  109. addr += 4;
  110. fprintf_fn (stream, " %d:[", val);
  111. if ((status = get_int (addr, &val, info)))
  112. goto fail;
  113. addr += 4;
  114. (*info->print_address_func) (val + insn_start, info);
  115. fprintf_fn (stream, " ]");
  116. }
  117. return addr - insn_start;
  118. }
  119. for (a = 0; op->arg[a]; a++)
  120. {
  121. unsigned char data[4];
  122. int val = 0;
  123. int i;
  124. int size = ASIZE (op->arg[a]);
  125. if ((status = info->read_memory_func (addr, data, size, info)))
  126. goto fail;
  127. val = (UNS (op->arg[0]) || ((data[0] & 0x80) == 0)) ? 0 : -1;
  128. for (i = 0; i < size; i++)
  129. val = (val << 8) | (data[i] & 0xff);
  130. if (PCREL (op->arg[a]))
  131. (*info->print_address_func) (val + insn_start, info);
  132. else
  133. fprintf_fn (stream, "%s%d", sep, val);
  134. sep = ",";
  135. addr += size;
  136. }
  137. return op->len;
  138. }
  139. fail:
  140. info->memory_error_func (status, addr, info);
  141. return -1;
  142. }