rx-dis.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* Disassembler code for Renesas RX.
  2. Copyright (C) 2008-2015 Free Software Foundation, Inc.
  3. Contributed by Red Hat.
  4. Written by DJ Delorie.
  5. This file is part of the GNU opcodes library.
  6. This library is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3, or (at your option)
  9. any later version.
  10. It is distributed in the hope that it will be useful, but WITHOUT
  11. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  13. License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  17. MA 02110-1301, USA. */
  18. #include "sysdep.h"
  19. #include <stdio.h>
  20. #include "bfd.h"
  21. #include "dis-asm.h"
  22. #include "opcode/rx.h"
  23. typedef struct
  24. {
  25. bfd_vma pc;
  26. disassemble_info * dis;
  27. } RX_Data;
  28. static int
  29. rx_get_byte (void * vdata)
  30. {
  31. bfd_byte buf[1];
  32. RX_Data *rx_data = (RX_Data *) vdata;
  33. rx_data->dis->read_memory_func (rx_data->pc,
  34. buf,
  35. 1,
  36. rx_data->dis);
  37. rx_data->pc ++;
  38. return buf[0];
  39. }
  40. static char const * size_names[RX_MAX_SIZE] =
  41. {
  42. "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l", "<error>"
  43. };
  44. static char const * opsize_names[RX_MAX_SIZE] =
  45. {
  46. "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l", "<error>"
  47. };
  48. static char const * register_names[] =
  49. {
  50. /* general registers */
  51. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  52. "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  53. /* control register */
  54. "psw", "pc", "usp", "fpsw", NULL, NULL, NULL, NULL,
  55. "bpsw", "bpc", "isp", "fintv", "intb", NULL, NULL, NULL,
  56. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  57. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  58. };
  59. static char const * condition_names[] =
  60. {
  61. /* condition codes */
  62. "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
  63. "ge", "lt", "gt", "le", "o", "no", "always", "never"
  64. };
  65. static const char * flag_names[] =
  66. {
  67. "c", "z", "s", "o", "", "", "", "",
  68. "", "", "", "", "", "", "", "",
  69. "i", "u", "", "", "", "", "", ""
  70. "", "", "", "", "", "", "", "",
  71. };
  72. int
  73. print_insn_rx (bfd_vma addr, disassemble_info * dis)
  74. {
  75. int rv;
  76. RX_Data rx_data;
  77. RX_Opcode_Decoded opcode;
  78. const char * s;
  79. rx_data.pc = addr;
  80. rx_data.dis = dis;
  81. rv = rx_decode_opcode (addr, &opcode, rx_get_byte, &rx_data);
  82. dis->bytes_per_line = 10;
  83. #define PR (dis->fprintf_func)
  84. #define PS (dis->stream)
  85. #define PC(c) PR (PS, "%c", c)
  86. /* Detect illegal instructions. */
  87. if (opcode.op[0].size == RX_Bad_Size
  88. || register_names [opcode.op[0].reg] == NULL
  89. || register_names [opcode.op[1].reg] == NULL
  90. || register_names [opcode.op[2].reg] == NULL)
  91. {
  92. bfd_byte buf[10];
  93. int i;
  94. PR (PS, ".byte ");
  95. rx_data.dis->read_memory_func (rx_data.pc - rv, buf, rv, rx_data.dis);
  96. for (i = 0 ; i < rv; i++)
  97. PR (PS, "0x%02x ", buf[i]);
  98. return rv;
  99. }
  100. for (s = opcode.syntax; *s; s++)
  101. {
  102. if (*s != '%')
  103. {
  104. PC (*s);
  105. }
  106. else
  107. {
  108. RX_Opcode_Operand * oper;
  109. int do_size = 0;
  110. int do_hex = 0;
  111. int do_addr = 0;
  112. s ++;
  113. if (*s == 'S')
  114. {
  115. do_size = 1;
  116. s++;
  117. }
  118. if (*s == 'x')
  119. {
  120. do_hex = 1;
  121. s++;
  122. }
  123. if (*s == 'a')
  124. {
  125. do_addr = 1;
  126. s++;
  127. }
  128. switch (*s)
  129. {
  130. case '%':
  131. PC ('%');
  132. break;
  133. case 's':
  134. PR (PS, "%s", opsize_names[opcode.size]);
  135. break;
  136. case '0':
  137. case '1':
  138. case '2':
  139. oper = opcode.op + *s - '0';
  140. if (do_size)
  141. {
  142. if (oper->type == RX_Operand_Indirect)
  143. PR (PS, "%s", size_names[oper->size]);
  144. }
  145. else
  146. switch (oper->type)
  147. {
  148. case RX_Operand_Immediate:
  149. if (do_addr)
  150. dis->print_address_func (oper->addend, dis);
  151. else if (do_hex
  152. || oper->addend > 999
  153. || oper->addend < -999)
  154. PR (PS, "%#x", oper->addend);
  155. else
  156. PR (PS, "%d", oper->addend);
  157. break;
  158. case RX_Operand_Register:
  159. case RX_Operand_TwoReg:
  160. PR (PS, "%s", register_names[oper->reg]);
  161. break;
  162. case RX_Operand_Indirect:
  163. if (oper->addend)
  164. PR (PS, "%d[%s]", oper->addend, register_names[oper->reg]);
  165. else
  166. PR (PS, "[%s]", register_names[oper->reg]);
  167. break;
  168. case RX_Operand_Postinc:
  169. PR (PS, "[%s+]", register_names[oper->reg]);
  170. break;
  171. case RX_Operand_Predec:
  172. PR (PS, "[-%s]", register_names[oper->reg]);
  173. break;
  174. case RX_Operand_Condition:
  175. PR (PS, "%s", condition_names[oper->reg]);
  176. break;
  177. case RX_Operand_Flag:
  178. PR (PS, "%s", flag_names[oper->reg]);
  179. break;
  180. default:
  181. PR (PS, "[???]");
  182. break;
  183. }
  184. }
  185. }
  186. }
  187. return rv;
  188. }