xgate-dis.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /* xgate-dis.c -- Freescale XGATE disassembly
  2. Copyright (C) 2009-2022 Free Software Foundation, Inc.
  3. Written by Sean Keys (skeys@ipdatasys.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 <assert.h>
  19. #include "disassemble.h"
  20. #include "opintl.h"
  21. #include "libiberty.h"
  22. #include "ansidecl.h"
  23. #include "opcode/xgate.h"
  24. #define XGATE_TWO_BYTES 0x02
  25. #define XGATE_NINE_BITS 0x1FF
  26. #define XGATE_TEN_BITS 0x3FF
  27. #define XGATE_NINE_SIGNBIT 0x100
  28. #define XGATE_TEN_SIGNBIT 0x200
  29. /* Structures. */
  30. struct decodeInfo
  31. {
  32. unsigned int operMask;
  33. unsigned int operMasksRegisterBits;
  34. struct xgate_opcode *opcodePTR;
  35. };
  36. /* Prototypes for local functions. */
  37. static int print_insn (bfd_vma, struct disassemble_info *);
  38. static int read_memory (bfd_vma, bfd_byte*, int, struct disassemble_info *);
  39. static int ripBits (unsigned int *, int,
  40. struct xgate_opcode *, unsigned int);
  41. static int macro_search (char *, char *);
  42. static struct decodeInfo * find_match (unsigned int);
  43. /* Statics. */
  44. static struct decodeInfo *decodeTable;
  45. static int initialized;
  46. static char previousOpName[10];
  47. static unsigned int perviousBin;
  48. /* Disassemble one instruction at address 'memaddr'. Returns the number
  49. of bytes used by that instruction. */
  50. static int
  51. print_insn (bfd_vma memaddr, struct disassemble_info* info)
  52. {
  53. int status;
  54. unsigned int raw_code;
  55. char *s = 0;
  56. long bytesRead = 0;
  57. int i = 0;
  58. struct xgate_opcode *opcodePTR = (struct xgate_opcode*) xgate_opcodes;
  59. struct decodeInfo *decodeTablePTR = 0;
  60. struct decodeInfo *decodePTR = 0;
  61. unsigned int operandRegisterBits = 0;
  62. signed int relAddr = 0;
  63. signed int operandOne = 0;
  64. signed int operandTwo = 0;
  65. bfd_byte buffer[4];
  66. bfd_vma absAddress;
  67. unsigned int operMaskReg = 0;
  68. /* Initialize our array of opcode masks and check them against our constant
  69. table. */
  70. if (!initialized)
  71. {
  72. decodeTable = xmalloc (sizeof (struct decodeInfo) * xgate_num_opcodes);
  73. for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes;
  74. i++, decodeTablePTR++, opcodePTR++)
  75. {
  76. unsigned int bin = 0;
  77. unsigned int mask = 0;
  78. for (s = opcodePTR->format; *s; s++)
  79. {
  80. bin <<= 1;
  81. mask <<= 1;
  82. operandRegisterBits <<= 1;
  83. bin |= (*s == '1');
  84. mask |= (*s == '0' || *s == '1');
  85. operandRegisterBits |= (*s == 'r');
  86. }
  87. /* Asserting will uncover inconsistencies in our table. */
  88. assert ((s - opcodePTR->format) == 16 || (s - opcodePTR->format) == 32);
  89. assert (opcodePTR->bin_opcode == bin);
  90. decodeTablePTR->operMask = mask;
  91. decodeTablePTR->operMasksRegisterBits = operandRegisterBits;
  92. decodeTablePTR->opcodePTR = opcodePTR;
  93. }
  94. initialized = 1;
  95. }
  96. /* Read 16 bits. */
  97. bytesRead += XGATE_TWO_BYTES;
  98. status = read_memory (memaddr, buffer, XGATE_TWO_BYTES, info);
  99. if (status == 0)
  100. {
  101. raw_code = buffer[0];
  102. raw_code <<= 8;
  103. raw_code += buffer[1];
  104. decodePTR = find_match (raw_code);
  105. if (decodePTR)
  106. {
  107. operMaskReg = decodePTR->operMasksRegisterBits;
  108. (*info->fprintf_func)(info->stream, "%s", decodePTR->opcodePTR->name);
  109. /* First we compare the shorthand format of the constraints. If we
  110. still are unable to pinpoint the operands
  111. we analyze the opcodes constraint string. */
  112. if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON_R_C))
  113. {
  114. (*info->fprintf_func)(info->stream, " R%x, CCR",
  115. (raw_code >> 8) & 0x7);
  116. }
  117. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON_C_R))
  118. {
  119. (*info->fprintf_func)(info->stream, " CCR, R%x",
  120. (raw_code >> 8) & 0x7);
  121. }
  122. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON_R_P))
  123. {
  124. (*info->fprintf_func)(info->stream, " R%x, PC",
  125. (raw_code >> 8) & 0x7);
  126. }
  127. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_TRI))
  128. {
  129. (*info->fprintf_func)(info->stream, " R%x, R%x, R%x",
  130. (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
  131. (raw_code >> 2) & 0x7);
  132. }
  133. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IDR))
  134. {
  135. if (raw_code & 0x01)
  136. {
  137. (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x+)",
  138. (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
  139. (raw_code >> 2) & 0x7);
  140. }
  141. else if (raw_code & 0x02)
  142. {
  143. (*info->fprintf_func)(info->stream, " R%x, (R%x, -R%x)",
  144. (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
  145. (raw_code >> 2) & 0x7);
  146. }
  147. else
  148. {
  149. (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x)",
  150. (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
  151. (raw_code >> 2) & 0x7);
  152. }
  153. }
  154. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_DYA))
  155. {
  156. operandOne = ripBits (&operMaskReg, 3, decodePTR->opcodePTR, raw_code);
  157. operandTwo = ripBits (&operMaskReg, 3, decodePTR->opcodePTR, raw_code);
  158. ( *info->fprintf_func)(info->stream, " R%x, R%x", operandOne,
  159. operandTwo);
  160. }
  161. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IDO5))
  162. {
  163. (*info->fprintf_func)(info->stream, " R%x, (R%x, #0x%x)",
  164. (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, raw_code & 0x1f);
  165. }
  166. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON))
  167. {
  168. operandOne = ripBits (&operMaskReg, 3, decodePTR->opcodePTR,
  169. raw_code);
  170. (*info->fprintf_func)(info->stream, " R%x", operandOne);
  171. }
  172. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_REL9))
  173. {
  174. /* If address is negative handle it accordingly. */
  175. if (raw_code & XGATE_NINE_SIGNBIT)
  176. {
  177. relAddr = XGATE_NINE_BITS >> 1; /* Clip sign bit. */
  178. relAddr = ~relAddr; /* Make signed. */
  179. relAddr |= (raw_code & 0xFF) + 1; /* Apply our value. */
  180. relAddr *= 2; /* Multiply by two as per processor docs. */
  181. }
  182. else
  183. {
  184. relAddr = raw_code & 0xff;
  185. relAddr = relAddr * 2 + 2;
  186. }
  187. (*info->fprintf_func)(info->stream, " *%d", relAddr);
  188. (*info->fprintf_func)(info->stream, " Abs* 0x");
  189. (*info->print_address_func)(memaddr + relAddr, info);
  190. }
  191. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_REL10))
  192. {
  193. /* If address is negative handle it accordingly. */
  194. if (raw_code & XGATE_TEN_SIGNBIT)
  195. {
  196. relAddr = XGATE_TEN_BITS >> 1; /* Clip sign bit. */
  197. relAddr = ~relAddr; /* Make signed. */
  198. relAddr |= (raw_code & 0x1FF) + 1; /* Apply our value. */
  199. relAddr *= 2; /* Multiply by two as per processor docs. */
  200. }
  201. else
  202. {
  203. relAddr = raw_code & 0x1FF;
  204. relAddr = relAddr * 2 + 2;
  205. }
  206. (*info->fprintf_func)(info->stream, " *%d", relAddr);
  207. (*info->fprintf_func)(info->stream, " Abs* 0x");
  208. (*info->print_address_func)(memaddr + relAddr, info);
  209. }
  210. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IMM4))
  211. {
  212. (*info->fprintf_func)(info->stream, " R%x, #0x%02x",
  213. (raw_code >> 8) & 0x7, (raw_code >> 4) & 0xF);
  214. }
  215. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IMM8))
  216. {
  217. if (macro_search (decodePTR->opcodePTR->name, previousOpName) &&
  218. previousOpName[0])
  219. {
  220. absAddress = (0xFF & raw_code) << 8;
  221. absAddress |= perviousBin & 0xFF;
  222. (*info->fprintf_func)(info->stream, " R%x, #0x%02x Abs* 0x",
  223. (raw_code >> 8) & 0x7, raw_code & 0xff);
  224. (*info->print_address_func)(absAddress, info);
  225. previousOpName[0] = 0;
  226. }
  227. else
  228. {
  229. strcpy (previousOpName, decodePTR->opcodePTR->name);
  230. (*info->fprintf_func)(info->stream, " R%x, #0x%02x",
  231. (raw_code >> 8) & 0x7, raw_code & 0xff);
  232. }
  233. }
  234. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IMM3))
  235. {
  236. (*info->fprintf_func)(info->stream, " #0x%x",
  237. (raw_code >> 8) & 0x7);
  238. }
  239. else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_INH))
  240. {
  241. }
  242. else
  243. {
  244. (*info->fprintf_func)(info->stream, " unhandled mode %s",
  245. decodePTR->opcodePTR->constraints);
  246. }
  247. perviousBin = raw_code;
  248. }
  249. else
  250. {
  251. (*info->fprintf_func)(info->stream,
  252. " unable to find opcode match #0%x", raw_code);
  253. }
  254. }
  255. return bytesRead;
  256. }
  257. int
  258. print_insn_xgate (bfd_vma memaddr, struct disassemble_info* info)
  259. {
  260. return print_insn (memaddr, info);
  261. }
  262. static int
  263. read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
  264. struct disassemble_info* info)
  265. {
  266. int status;
  267. status = (*info->read_memory_func) (memaddr, buffer, size, info);
  268. if (status != 0)
  269. {
  270. (*info->memory_error_func) (status, memaddr, info);
  271. return -1;
  272. }
  273. return 0;
  274. }
  275. static int
  276. ripBits (unsigned int *operandBitsRemaining,
  277. int numBitsRequested,
  278. struct xgate_opcode *opcodePTR,
  279. unsigned int memory)
  280. {
  281. unsigned int currentBit;
  282. unsigned int operand = 0;
  283. int numBitsFound;
  284. for (numBitsFound = 0, currentBit = 1u << ((opcodePTR->size * 8) - 1);
  285. numBitsFound < numBitsRequested && currentBit != 0;
  286. currentBit >>= 1)
  287. {
  288. if (currentBit & *operandBitsRemaining)
  289. {
  290. *operandBitsRemaining &= ~(currentBit); /* Consume the current bit. */
  291. operand <<= 1; /* Make room for our next bit. */
  292. numBitsFound++;
  293. operand |= (currentBit & memory) > 0;
  294. }
  295. }
  296. return operand;
  297. }
  298. static int
  299. macro_search (char *currentName, char *lastName)
  300. {
  301. int i;
  302. int length = 0;
  303. char *where;
  304. for (i = 0; i < xgate_num_opcodes; i++)
  305. {
  306. where = strstr (xgate_opcodes[i].constraints, lastName);
  307. if (where)
  308. {
  309. length = strlen (where);
  310. }
  311. if (length)
  312. {
  313. where = strstr (xgate_opcodes[i].constraints, currentName);
  314. if (where)
  315. {
  316. length = strlen (where);
  317. return 1;
  318. }
  319. }
  320. }
  321. return 0;
  322. }
  323. static struct decodeInfo *
  324. find_match (unsigned int raw_code)
  325. {
  326. struct decodeInfo *decodeTablePTR = 0;
  327. int i;
  328. for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes;
  329. i++, decodeTablePTR++)
  330. {
  331. if ((raw_code & decodeTablePTR->operMask)
  332. == decodeTablePTR->opcodePTR->bin_opcode)
  333. {
  334. /* Make sure we didn't run into a macro or alias. */
  335. if (decodeTablePTR->opcodePTR->cycles_min != 0)
  336. {
  337. return decodeTablePTR;
  338. break;
  339. }
  340. else
  341. continue;
  342. }
  343. }
  344. return 0;
  345. }