mcore-dis.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /* Disassemble Motorola M*Core instructions.
  2. Copyright (C) 1993-2017 Free Software Foundation, Inc.
  3. This file is part of the GNU opcodes library.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. It is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  11. License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  15. MA 02110-1301, USA. */
  16. #include "sysdep.h"
  17. #include <stdio.h>
  18. #include "libiberty.h"
  19. #define STATIC_TABLE
  20. #define DEFINE_TABLE
  21. #include "mcore-opc.h"
  22. #include "disassemble.h"
  23. /* Mask for each mcore_opclass: */
  24. static const unsigned short imsk[] = {
  25. /* O0 */ 0xFFFF,
  26. /* OT */ 0xFFFC,
  27. /* O1 */ 0xFFF0,
  28. /* OC */ 0xFE00,
  29. /* O2 */ 0xFF00,
  30. /* X1 */ 0xFFF0,
  31. /* OI */ 0xFE00,
  32. /* OB */ 0xFE00,
  33. /* OMa */ 0xFFF0,
  34. /* SI */ 0xFE00,
  35. /* I7 */ 0xF800,
  36. /* LS */ 0xF000,
  37. /* BR */ 0xF800,
  38. /* BL */ 0xFF00,
  39. /* LR */ 0xF000,
  40. /* LJ */ 0xFF00,
  41. /* RM */ 0xFFF0,
  42. /* RQ */ 0xFFF0,
  43. /* JSR */ 0xFFF0,
  44. /* JMP */ 0xFFF0,
  45. /* OBRa*/ 0xFFF0,
  46. /* OBRb*/ 0xFF80,
  47. /* OBRc*/ 0xFF00,
  48. /* OBR2*/ 0xFE00,
  49. /* O1R1*/ 0xFFF0,
  50. /* OMb */ 0xFF80,
  51. /* OMc */ 0xFF00,
  52. /* SIa */ 0xFE00,
  53. /* MULSH */ 0xFF00,
  54. /* OPSR */ 0xFFF8, /* psrset/psrclr */
  55. /* JC */ 0, /* JC,JU,JL don't appear in object */
  56. /* JU */ 0,
  57. /* JL */ 0,
  58. /* RSI */ 0,
  59. /* DO21*/ 0,
  60. /* OB2 */ 0 /* OB2 won't appear in object. */
  61. };
  62. static const char *grname[] = {
  63. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  64. "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
  65. };
  66. static const char X[] = "??";
  67. static const char *crname[] = {
  68. "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
  69. "ss2", "ss3", "ss4", "gcr", "gsr", X, X, X,
  70. X, X, X, X, X, X, X, X,
  71. X, X, X, X, X, X, X, X
  72. };
  73. static const unsigned isiz[] = { 2, 0, 1, 0 };
  74. int
  75. print_insn_mcore (bfd_vma memaddr,
  76. struct disassemble_info *info)
  77. {
  78. unsigned char ibytes[4];
  79. fprintf_ftype print_func = info->fprintf_func;
  80. void *stream = info->stream;
  81. unsigned short inst;
  82. unsigned int i;
  83. int status;
  84. info->bytes_per_chunk = 2;
  85. status = info->read_memory_func (memaddr, ibytes, 2, info);
  86. if (status != 0)
  87. {
  88. info->memory_error_func (status, memaddr, info);
  89. return -1;
  90. }
  91. if (info->endian == BFD_ENDIAN_BIG)
  92. inst = (ibytes[0] << 8) | ibytes[1];
  93. else if (info->endian == BFD_ENDIAN_LITTLE)
  94. inst = (ibytes[1] << 8) | ibytes[0];
  95. else
  96. abort ();
  97. /* Just a linear search of the table. */
  98. for (i = 0; i < ARRAY_SIZE (mcore_table); i++)
  99. if (mcore_table[i].inst == (inst & imsk[mcore_table[i].opclass]))
  100. break;
  101. if (i == ARRAY_SIZE (mcore_table))
  102. (*print_func) (stream, ".short 0x%04x", inst);
  103. else
  104. {
  105. const char *name = grname[inst & 0x0F];
  106. (*print_func) (stream, "%s", mcore_table[i].name);
  107. switch (mcore_table[i].opclass)
  108. {
  109. case O0:
  110. break;
  111. case OT:
  112. (*print_func) (stream, "\t%d", inst & 0x3);
  113. break;
  114. case O1:
  115. case JMP:
  116. case JSR:
  117. (*print_func) (stream, "\t%s", name);
  118. break;
  119. case OC:
  120. (*print_func) (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]);
  121. break;
  122. case O1R1:
  123. (*print_func) (stream, "\t%s, r1", name);
  124. break;
  125. case MULSH:
  126. case O2:
  127. (*print_func) (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]);
  128. break;
  129. case X1:
  130. (*print_func) (stream, "\tr1, %s", name);
  131. break;
  132. case OI:
  133. (*print_func) (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1);
  134. break;
  135. case RM:
  136. (*print_func) (stream, "\t%s-r15, (r0)", name);
  137. break;
  138. case RQ:
  139. (*print_func) (stream, "\tr4-r7, (%s)", name);
  140. break;
  141. case OB:
  142. case OBRa:
  143. case OBRb:
  144. case OBRc:
  145. case SI:
  146. case SIa:
  147. case OMa:
  148. case OMb:
  149. case OMc:
  150. (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x1F);
  151. break;
  152. case I7:
  153. (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x7F);
  154. break;
  155. case LS:
  156. (*print_func) (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
  157. name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
  158. break;
  159. case BR:
  160. {
  161. long val = inst & 0x3FF;
  162. if (inst & 0x400)
  163. val |= 0xFFFFFC00;
  164. (*print_func) (stream, "\t0x%lx", (long)(memaddr + 2 + (val << 1)));
  165. if (strcmp (mcore_table[i].name, "bsr") == 0)
  166. {
  167. /* For bsr, we'll try to get a symbol for the target. */
  168. val = memaddr + 2 + (val << 1);
  169. if (info->print_address_func && val != 0)
  170. {
  171. (*print_func) (stream, "\t// ");
  172. info->print_address_func (val, info);
  173. }
  174. }
  175. }
  176. break;
  177. case BL:
  178. {
  179. long val;
  180. val = (inst & 0x000F);
  181. (*print_func) (stream, "\t%s, 0x%lx",
  182. grname[(inst >> 4) & 0xF],
  183. (long) (memaddr - (val << 1)));
  184. }
  185. break;
  186. case LR:
  187. {
  188. unsigned long val;
  189. val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
  190. /* We are not reading an instruction, so allow
  191. reads to extend beyond the next symbol. */
  192. info->stop_vma = 0;
  193. status = info->read_memory_func (val, ibytes, 4, info);
  194. if (status != 0)
  195. {
  196. info->memory_error_func (status, memaddr, info);
  197. break;
  198. }
  199. if (info->endian == BFD_ENDIAN_LITTLE)
  200. val = (ibytes[3] << 24) | (ibytes[2] << 16)
  201. | (ibytes[1] << 8) | (ibytes[0]);
  202. else
  203. val = (ibytes[0] << 24) | (ibytes[1] << 16)
  204. | (ibytes[2] << 8) | (ibytes[3]);
  205. /* Removed [] around literal value to match ABI syntax 12/95. */
  206. (*print_func) (stream, "\t%s, 0x%lX", grname[(inst >> 8) & 0xF], val);
  207. if (val == 0)
  208. (*print_func) (stream, "\t// from address pool at 0x%lx",
  209. (long) (memaddr + 2
  210. + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
  211. }
  212. break;
  213. case LJ:
  214. {
  215. unsigned long val;
  216. val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
  217. /* We are not reading an instruction, so allow
  218. reads to extend beyond the next symbol. */
  219. info->stop_vma = 0;
  220. status = info->read_memory_func (val, ibytes, 4, info);
  221. if (status != 0)
  222. {
  223. info->memory_error_func (status, memaddr, info);
  224. break;
  225. }
  226. if (info->endian == BFD_ENDIAN_LITTLE)
  227. val = (ibytes[3] << 24) | (ibytes[2] << 16)
  228. | (ibytes[1] << 8) | (ibytes[0]);
  229. else
  230. val = (ibytes[0] << 24) | (ibytes[1] << 16)
  231. | (ibytes[2] << 8) | (ibytes[3]);
  232. /* Removed [] around literal value to match ABI syntax 12/95. */
  233. (*print_func) (stream, "\t0x%lX", val);
  234. /* For jmpi/jsri, we'll try to get a symbol for the target. */
  235. if (info->print_address_func && val != 0)
  236. {
  237. (*print_func) (stream, "\t// ");
  238. info->print_address_func (val, info);
  239. }
  240. else
  241. {
  242. (*print_func) (stream, "\t// from address pool at 0x%lx",
  243. (long) (memaddr + 2
  244. + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
  245. }
  246. }
  247. break;
  248. case OPSR:
  249. {
  250. static char *fields[] = {
  251. "af", "ie", "fe", "fe,ie",
  252. "ee", "ee,ie", "ee,fe", "ee,fe,ie"
  253. };
  254. (*print_func) (stream, "\t%s", fields[inst & 0x7]);
  255. }
  256. break;
  257. default:
  258. /* If the disassembler lags the instruction set. */
  259. (*print_func) (stream, "\tundecoded operands, inst is 0x%04x", inst);
  260. break;
  261. }
  262. }
  263. /* Say how many bytes we consumed. */
  264. return 2;
  265. }