You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4427 lines
104 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2006 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2009 by David Brownell *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; either version 2 of the License, or *
  10. * (at your option) any later version. *
  11. * *
  12. * This program is distributed in the hope that it will be useful, *
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15. * GNU General Public License for more details. *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with this program; if not, write to the *
  19. * Free Software Foundation, Inc., *
  20. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  21. ***************************************************************************/
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25. #include "target.h"
  26. #include "arm_disassembler.h"
  27. #include <helper/log.h>
  28. /*
  29. * This disassembler supports two main functions for OpenOCD:
  30. *
  31. * - Various "disassemble" commands. OpenOCD can serve as a
  32. * machine-language debugger, without help from GDB.
  33. *
  34. * - Single stepping. Not all ARM cores support hardware single
  35. * stepping. To work without that support, the debugger must
  36. * be able to decode instructions to find out where to put a
  37. * "next instruction" breakpoint.
  38. *
  39. * In addition, interpretation of ETM trace data needs some of the
  40. * decoding mechanisms.
  41. *
  42. * At this writing (September 2009) neither function is complete.
  43. *
  44. * - ARM decoding
  45. * * Old-style syntax (not UAL) is generally used
  46. * * VFP instructions are not understood (ARMv5 and later)
  47. * except as coprocessor 10/11 operations
  48. * * Most ARM instructions through ARMv6 are decoded, but some
  49. * of the post-ARMv4 opcodes may not be handled yet
  50. * * NEON instructions are not understood (ARMv7-A)
  51. *
  52. * - Thumb/Thumb2 decoding
  53. * * UAL syntax should be consistently used
  54. * * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should
  55. * be handled properly. Accordingly, so should the subset
  56. * used in Cortex-M0/M1; and "original" 16-bit Thumb from
  57. * ARMv4T and ARMv5T.
  58. * * Conditional effects of Thumb2 "IT" (if-then) instructions
  59. * are not handled: the affected instructions are not shown
  60. * with their now-conditional suffixes.
  61. * * Some ARMv6 and ARMv7-M Thumb2 instructions may not be
  62. * handled (minimally for coprocessor access).
  63. * * SIMD instructions, and some other Thumb2 instructions
  64. * from ARMv7-A, are not understood.
  65. *
  66. * - ThumbEE decoding
  67. * * As a Thumb2 variant, the Thumb2 comments (above) apply.
  68. * * Opcodes changed by ThumbEE mode are not handled; these
  69. * instructions wrongly decode as LDM and STM.
  70. *
  71. * - Jazelle decoding ... no support whatsoever for Jazelle mode
  72. * or decoding. ARM encourages use of the more generic ThumbEE
  73. * mode, instead of Jazelle mode, in current chips.
  74. *
  75. * - Single-step/emulation ... spotty support, which is only weakly
  76. * tested. Thumb2 is not supported. (Arguably a full simulator
  77. * is not needed to support just single stepping. Recognizing
  78. * branch vs non-branch instructions suffices, except when the
  79. * instruction faults and triggers a synchronous exception which
  80. * can be intercepted using other means.)
  81. *
  82. * ARM DDI 0406B "ARM Architecture Reference Manual, ARM v7-A and
  83. * ARM v7-R edition" gives the most complete coverage of the various
  84. * generations of ARM instructions. At this writing it is publicly
  85. * accessible to anyone willing to create an account at the ARM
  86. * web site; see http://www.arm.com/documentation/ for information.
  87. *
  88. * ARM DDI 0403C "ARMv7-M Architecture Reference Manual" provides
  89. * more details relevant to the Thumb2-only processors (such as
  90. * the Cortex-M implementations).
  91. */
  92. /* textual represenation of the condition field */
  93. /* ALways (default) is ommitted (empty string) */
  94. static const char *arm_condition_strings[] =
  95. {
  96. "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
  97. };
  98. /* make up for C's missing ROR */
  99. static uint32_t ror(uint32_t value, int places)
  100. {
  101. return (value >> places) | (value << (32 - places));
  102. }
  103. static int evaluate_unknown(uint32_t opcode,
  104. uint32_t address, struct arm_instruction *instruction)
  105. {
  106. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  107. snprintf(instruction->text, 128,
  108. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
  109. "\tUNDEFINED INSTRUCTION", address, opcode);
  110. return ERROR_OK;
  111. }
  112. static int evaluate_pld(uint32_t opcode,
  113. uint32_t address, struct arm_instruction *instruction)
  114. {
  115. /* PLD */
  116. if ((opcode & 0x0d70f000) == 0x0550f000)
  117. {
  118. instruction->type = ARM_PLD;
  119. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode);
  120. return ERROR_OK;
  121. }
  122. return evaluate_unknown(opcode, address, instruction);
  123. }
  124. static int evaluate_srs(uint32_t opcode,
  125. uint32_t address, struct arm_instruction *instruction)
  126. {
  127. const char *wback = (opcode & (1 << 21)) ? "!" : "";
  128. const char *mode = "";
  129. switch ((opcode >> 23) & 0x3) {
  130. case 0:
  131. mode = "DA";
  132. break;
  133. case 1:
  134. /* "IA" is default */
  135. break;
  136. case 2:
  137. mode = "DB";
  138. break;
  139. case 3:
  140. mode = "IB";
  141. break;
  142. }
  143. switch (opcode & 0x0e500000) {
  144. case 0x08400000:
  145. snprintf(instruction->text, 128, "0x%8.8" PRIx32
  146. "\t0x%8.8" PRIx32
  147. "\tSRS%s\tSP%s, #%d",
  148. address, opcode,
  149. mode, wback,
  150. (unsigned)(opcode & 0x1f));
  151. break;
  152. case 0x08100000:
  153. snprintf(instruction->text, 128, "0x%8.8" PRIx32
  154. "\t0x%8.8" PRIx32
  155. "\tRFE%s\tr%d%s",
  156. address, opcode,
  157. mode,
  158. (unsigned)((opcode >> 16) & 0xf), wback);
  159. break;
  160. default:
  161. return evaluate_unknown(opcode, address, instruction);
  162. }
  163. return ERROR_OK;
  164. }
  165. static int evaluate_swi(uint32_t opcode,
  166. uint32_t address, struct arm_instruction *instruction)
  167. {
  168. instruction->type = ARM_SWI;
  169. snprintf(instruction->text, 128,
  170. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVC %#6.6" PRIx32,
  171. address, opcode, (opcode & 0xffffff));
  172. return ERROR_OK;
  173. }
  174. static int evaluate_blx_imm(uint32_t opcode,
  175. uint32_t address, struct arm_instruction *instruction)
  176. {
  177. int offset;
  178. uint32_t immediate;
  179. uint32_t target_address;
  180. instruction->type = ARM_BLX;
  181. immediate = opcode & 0x00ffffff;
  182. /* sign extend 24-bit immediate */
  183. if (immediate & 0x00800000)
  184. offset = 0xff000000 | immediate;
  185. else
  186. offset = immediate;
  187. /* shift two bits left */
  188. offset <<= 2;
  189. /* odd/event halfword */
  190. if (opcode & 0x01000000)
  191. offset |= 0x2;
  192. target_address = address + 8 + offset;
  193. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", address, opcode, target_address);
  194. instruction->info.b_bl_bx_blx.reg_operand = -1;
  195. instruction->info.b_bl_bx_blx.target_address = target_address;
  196. return ERROR_OK;
  197. }
  198. static int evaluate_b_bl(uint32_t opcode,
  199. uint32_t address, struct arm_instruction *instruction)
  200. {
  201. uint8_t L;
  202. uint32_t immediate;
  203. int offset;
  204. uint32_t target_address;
  205. immediate = opcode & 0x00ffffff;
  206. L = (opcode & 0x01000000) >> 24;
  207. /* sign extend 24-bit immediate */
  208. if (immediate & 0x00800000)
  209. offset = 0xff000000 | immediate;
  210. else
  211. offset = immediate;
  212. /* shift two bits left */
  213. offset <<= 2;
  214. target_address = address + 8 + offset;
  215. if (L)
  216. instruction->type = ARM_BL;
  217. else
  218. instruction->type = ARM_B;
  219. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32 , address, opcode,
  220. (L) ? "L" : "", COND(opcode), target_address);
  221. instruction->info.b_bl_bx_blx.reg_operand = -1;
  222. instruction->info.b_bl_bx_blx.target_address = target_address;
  223. return ERROR_OK;
  224. }
  225. /* Coprocessor load/store and double register transfers */
  226. /* both normal and extended instruction space (condition field b1111) */
  227. static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
  228. uint32_t address, struct arm_instruction *instruction)
  229. {
  230. uint8_t cp_num = (opcode & 0xf00) >> 8;
  231. /* MCRR or MRRC */
  232. if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
  233. {
  234. uint8_t cp_opcode, Rd, Rn, CRm;
  235. char *mnemonic;
  236. cp_opcode = (opcode & 0xf0) >> 4;
  237. Rd = (opcode & 0xf000) >> 12;
  238. Rn = (opcode & 0xf0000) >> 16;
  239. CRm = (opcode & 0xf);
  240. /* MCRR */
  241. if ((opcode & 0x0ff00000) == 0x0c400000)
  242. {
  243. instruction->type = ARM_MCRR;
  244. mnemonic = "MCRR";
  245. }
  246. /* MRRC */
  247. if ((opcode & 0x0ff00000) == 0x0c500000)
  248. {
  249. instruction->type = ARM_MRRC;
  250. mnemonic = "MRRC";
  251. }
  252. snprintf(instruction->text, 128,
  253. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
  254. "\t%s%s%s p%i, %x, r%i, r%i, c%i",
  255. address, opcode, mnemonic,
  256. ((opcode & 0xf0000000) == 0xf0000000)
  257. ? "2" : COND(opcode),
  258. COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
  259. }
  260. else /* LDC or STC */
  261. {
  262. uint8_t CRd, Rn, offset;
  263. uint8_t U, N;
  264. char *mnemonic;
  265. char addressing_mode[32];
  266. CRd = (opcode & 0xf000) >> 12;
  267. Rn = (opcode & 0xf0000) >> 16;
  268. offset = (opcode & 0xff) << 2;
  269. /* load/store */
  270. if (opcode & 0x00100000)
  271. {
  272. instruction->type = ARM_LDC;
  273. mnemonic = "LDC";
  274. }
  275. else
  276. {
  277. instruction->type = ARM_STC;
  278. mnemonic = "STC";
  279. }
  280. U = (opcode & 0x00800000) >> 23;
  281. N = (opcode & 0x00400000) >> 22;
  282. /* addressing modes */
  283. if ((opcode & 0x01200000) == 0x01000000) /* offset */
  284. snprintf(addressing_mode, 32, "[r%i, #%s%d]",
  285. Rn, U ? "" : "-", offset);
  286. else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */
  287. snprintf(addressing_mode, 32, "[r%i, #%s%d]!",
  288. Rn, U ? "" : "-", offset);
  289. else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */
  290. snprintf(addressing_mode, 32, "[r%i], #%s%d",
  291. Rn, U ? "" : "-", offset);
  292. else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
  293. snprintf(addressing_mode, 32, "[r%i], {%d}",
  294. Rn, offset >> 2);
  295. snprintf(instruction->text, 128, "0x%8.8" PRIx32
  296. "\t0x%8.8" PRIx32
  297. "\t%s%s%s p%i, c%i, %s",
  298. address, opcode, mnemonic,
  299. ((opcode & 0xf0000000) == 0xf0000000)
  300. ? "2" : COND(opcode),
  301. (opcode & (1 << 22)) ? "L" : "",
  302. cp_num, CRd, addressing_mode);
  303. }
  304. return ERROR_OK;
  305. }
  306. /* Coprocessor data processing instructions */
  307. /* Coprocessor register transfer instructions */
  308. /* both normal and extended instruction space (condition field b1111) */
  309. static int evaluate_cdp_mcr_mrc(uint32_t opcode,
  310. uint32_t address, struct arm_instruction *instruction)
  311. {
  312. const char *cond;
  313. char* mnemonic;
  314. uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
  315. cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
  316. cp_num = (opcode & 0xf00) >> 8;
  317. CRd_Rd = (opcode & 0xf000) >> 12;
  318. CRn = (opcode & 0xf0000) >> 16;
  319. CRm = (opcode & 0xf);
  320. opcode_2 = (opcode & 0xe0) >> 5;
  321. /* CDP or MRC/MCR */
  322. if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */
  323. {
  324. if (opcode & 0x00100000) /* bit 20 set -> MRC */
  325. {
  326. instruction->type = ARM_MRC;
  327. mnemonic = "MRC";
  328. }
  329. else /* bit 20 not set -> MCR */
  330. {
  331. instruction->type = ARM_MCR;
  332. mnemonic = "MCR";
  333. }
  334. opcode_1 = (opcode & 0x00e00000) >> 21;
  335. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x",
  336. address, opcode, mnemonic, cond,
  337. cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
  338. }
  339. else /* bit 4 not set -> CDP */
  340. {
  341. instruction->type = ARM_CDP;
  342. mnemonic = "CDP";
  343. opcode_1 = (opcode & 0x00f00000) >> 20;
  344. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x",
  345. address, opcode, mnemonic, cond,
  346. cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
  347. }
  348. return ERROR_OK;
  349. }
  350. /* Load/store instructions */
  351. static int evaluate_load_store(uint32_t opcode,
  352. uint32_t address, struct arm_instruction *instruction)
  353. {
  354. uint8_t I, P, U, B, W, L;
  355. uint8_t Rn, Rd;
  356. char *operation; /* "LDR" or "STR" */
  357. char *suffix; /* "", "B", "T", "BT" */
  358. char offset[32];
  359. /* examine flags */
  360. I = (opcode & 0x02000000) >> 25;
  361. P = (opcode & 0x01000000) >> 24;
  362. U = (opcode & 0x00800000) >> 23;
  363. B = (opcode & 0x00400000) >> 22;
  364. W = (opcode & 0x00200000) >> 21;
  365. L = (opcode & 0x00100000) >> 20;
  366. /* target register */
  367. Rd = (opcode & 0xf000) >> 12;
  368. /* base register */
  369. Rn = (opcode & 0xf0000) >> 16;
  370. instruction->info.load_store.Rd = Rd;
  371. instruction->info.load_store.Rn = Rn;
  372. instruction->info.load_store.U = U;
  373. /* determine operation */
  374. if (L)
  375. operation = "LDR";
  376. else
  377. operation = "STR";
  378. /* determine instruction type and suffix */
  379. if (B)
  380. {
  381. if ((P == 0) && (W == 1))
  382. {
  383. if (L)
  384. instruction->type = ARM_LDRBT;
  385. else
  386. instruction->type = ARM_STRBT;
  387. suffix = "BT";
  388. }
  389. else
  390. {
  391. if (L)
  392. instruction->type = ARM_LDRB;
  393. else
  394. instruction->type = ARM_STRB;
  395. suffix = "B";
  396. }
  397. }
  398. else
  399. {
  400. if ((P == 0) && (W == 1))
  401. {
  402. if (L)
  403. instruction->type = ARM_LDRT;
  404. else
  405. instruction->type = ARM_STRT;
  406. suffix = "T";
  407. }
  408. else
  409. {
  410. if (L)
  411. instruction->type = ARM_LDR;
  412. else
  413. instruction->type = ARM_STR;
  414. suffix = "";
  415. }
  416. }
  417. if (!I) /* #+-<offset_12> */
  418. {
  419. uint32_t offset_12 = (opcode & 0xfff);
  420. if (offset_12)
  421. snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
  422. else
  423. snprintf(offset, 32, "%s", "");
  424. instruction->info.load_store.offset_mode = 0;
  425. instruction->info.load_store.offset.offset = offset_12;
  426. }
  427. else /* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
  428. {
  429. uint8_t shift_imm, shift;
  430. uint8_t Rm;
  431. shift_imm = (opcode & 0xf80) >> 7;
  432. shift = (opcode & 0x60) >> 5;
  433. Rm = (opcode & 0xf);
  434. /* LSR encodes a shift by 32 bit as 0x0 */
  435. if ((shift == 0x1) && (shift_imm == 0x0))
  436. shift_imm = 0x20;
  437. /* ASR encodes a shift by 32 bit as 0x0 */
  438. if ((shift == 0x2) && (shift_imm == 0x0))
  439. shift_imm = 0x20;
  440. /* ROR by 32 bit is actually a RRX */
  441. if ((shift == 0x3) && (shift_imm == 0x0))
  442. shift = 0x4;
  443. instruction->info.load_store.offset_mode = 1;
  444. instruction->info.load_store.offset.reg.Rm = Rm;
  445. instruction->info.load_store.offset.reg.shift = shift;
  446. instruction->info.load_store.offset.reg.shift_imm = shift_imm;
  447. if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
  448. {
  449. snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
  450. }
  451. else /* +-<Rm>, <Shift>, #<shift_imm> */
  452. {
  453. switch (shift)
  454. {
  455. case 0x0: /* LSL */
  456. snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
  457. break;
  458. case 0x1: /* LSR */
  459. snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
  460. break;
  461. case 0x2: /* ASR */
  462. snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
  463. break;
  464. case 0x3: /* ROR */
  465. snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
  466. break;
  467. case 0x4: /* RRX */
  468. snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
  469. break;
  470. }
  471. }
  472. }
  473. if (P == 1)
  474. {
  475. if (W == 0) /* offset */
  476. {
  477. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
  478. address, opcode, operation, COND(opcode), suffix,
  479. Rd, Rn, offset);
  480. instruction->info.load_store.index_mode = 0;
  481. }
  482. else /* pre-indexed */
  483. {
  484. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
  485. address, opcode, operation, COND(opcode), suffix,
  486. Rd, Rn, offset);
  487. instruction->info.load_store.index_mode = 1;
  488. }
  489. }
  490. else /* post-indexed */
  491. {
  492. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
  493. address, opcode, operation, COND(opcode), suffix,
  494. Rd, Rn, offset);
  495. instruction->info.load_store.index_mode = 2;
  496. }
  497. return ERROR_OK;
  498. }
  499. static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp)
  500. {
  501. unsigned rm = (opcode >> 0) & 0xf;
  502. unsigned rd = (opcode >> 12) & 0xf;
  503. unsigned rn = (opcode >> 16) & 0xf;
  504. char *type, *rot;
  505. switch ((opcode >> 24) & 0x3) {
  506. case 0:
  507. type = "B16";
  508. break;
  509. case 1:
  510. sprintf(cp, "UNDEFINED");
  511. return ARM_UNDEFINED_INSTRUCTION;
  512. case 2:
  513. type = "B";
  514. break;
  515. default:
  516. type = "H";
  517. break;
  518. }
  519. switch ((opcode >> 10) & 0x3) {
  520. case 0:
  521. rot = "";
  522. break;
  523. case 1:
  524. rot = ", ROR #8";
  525. break;
  526. case 2:
  527. rot = ", ROR #16";
  528. break;
  529. default:
  530. rot = ", ROR #24";
  531. break;
  532. }
  533. if (rn == 0xf) {
  534. sprintf(cp, "%cXT%s%s\tr%d, r%d%s",
  535. (opcode & (1 << 22)) ? 'U' : 'S',
  536. type, COND(opcode),
  537. rd, rm, rot);
  538. return ARM_MOV;
  539. } else {
  540. sprintf(cp, "%cXTA%s%s\tr%d, r%d, r%d%s",
  541. (opcode & (1 << 22)) ? 'U' : 'S',
  542. type, COND(opcode),
  543. rd, rn, rm, rot);
  544. return ARM_ADD;
  545. }
  546. }
  547. static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp)
  548. {
  549. char *prefix;
  550. char *op;
  551. int type;
  552. switch ((opcode >> 20) & 0x7) {
  553. case 1:
  554. prefix = "S";
  555. break;
  556. case 2:
  557. prefix = "Q";
  558. break;
  559. case 3:
  560. prefix = "SH";
  561. break;
  562. case 5:
  563. prefix = "U";
  564. break;
  565. case 6:
  566. prefix = "UQ";
  567. break;
  568. case 7:
  569. prefix = "UH";
  570. break;
  571. default:
  572. goto undef;
  573. }
  574. switch ((opcode >> 5) & 0x7) {
  575. case 0:
  576. op = "ADD16";
  577. type = ARM_ADD;
  578. break;
  579. case 1:
  580. op = "ADDSUBX";
  581. type = ARM_ADD;
  582. break;
  583. case 2:
  584. op = "SUBADDX";
  585. type = ARM_SUB;
  586. break;
  587. case 3:
  588. op = "SUB16";
  589. type = ARM_SUB;
  590. break;
  591. case 4:
  592. op = "ADD8";
  593. type = ARM_ADD;
  594. break;
  595. case 7:
  596. op = "SUB8";
  597. type = ARM_SUB;
  598. break;
  599. default:
  600. goto undef;
  601. }
  602. sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode),
  603. (int) (opcode >> 12) & 0xf,
  604. (int) (opcode >> 16) & 0xf,
  605. (int) (opcode >> 0) & 0xf);
  606. return type;
  607. undef:
  608. /* these opcodes might be used someday */
  609. sprintf(cp, "UNDEFINED");
  610. return ARM_UNDEFINED_INSTRUCTION;
  611. }
  612. /* ARMv6 and later support "media" instructions (includes SIMD) */
  613. static int evaluate_media(uint32_t opcode, uint32_t address,
  614. struct arm_instruction *instruction)
  615. {
  616. char *cp = instruction->text;
  617. char *mnemonic = NULL;
  618. sprintf(cp,
  619. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t",
  620. address, opcode);
  621. cp = strchr(cp, 0);
  622. /* parallel add/subtract */
  623. if ((opcode & 0x01800000) == 0x00000000) {
  624. instruction->type = evaluate_p_add_sub(opcode, address, cp);
  625. return ERROR_OK;
  626. }
  627. /* halfword pack */
  628. if ((opcode & 0x01f00020) == 0x00800000) {
  629. char *type, *shift;
  630. unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
  631. if (opcode & (1 << 6)) {
  632. type = "TB";
  633. shift = "ASR";
  634. if (imm == 0)
  635. imm = 32;
  636. } else {
  637. type = "BT";
  638. shift = "LSL";
  639. }
  640. sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d",
  641. type, COND(opcode),
  642. (int) (opcode >> 12) & 0xf,
  643. (int) (opcode >> 16) & 0xf,
  644. (int) (opcode >> 0) & 0xf,
  645. shift, imm);
  646. return ERROR_OK;
  647. }
  648. /* word saturate */
  649. if ((opcode & 0x01a00020) == 0x00a00000) {
  650. char *shift;
  651. unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
  652. if (opcode & (1 << 6)) {
  653. shift = "ASR";
  654. if (imm == 0)
  655. imm = 32;
  656. } else {
  657. shift = "LSL";
  658. }
  659. sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d",
  660. (opcode & (1 << 22)) ? 'U' : 'S',
  661. COND(opcode),
  662. (int) (opcode >> 12) & 0xf,
  663. (int) (opcode >> 16) & 0x1f,
  664. (int) (opcode >> 0) & 0xf,
  665. shift, imm);
  666. return ERROR_OK;
  667. }
  668. /* sign extension */
  669. if ((opcode & 0x018000f0) == 0x00800070) {
  670. instruction->type = evaluate_extend(opcode, address, cp);
  671. return ERROR_OK;
  672. }
  673. /* multiplies */
  674. if ((opcode & 0x01f00080) == 0x01000000) {
  675. unsigned rn = (opcode >> 12) & 0xf;
  676. if (rn != 0xf)
  677. sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d",
  678. (opcode & (1 << 6)) ? 'S' : 'A',
  679. (opcode & (1 << 5)) ? "X" : "",
  680. COND(opcode),
  681. (int) (opcode >> 16) & 0xf,
  682. (int) (opcode >> 0) & 0xf,
  683. (int) (opcode >> 8) & 0xf,
  684. rn);
  685. else
  686. sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d",
  687. (opcode & (1 << 6)) ? 'S' : 'A',
  688. (opcode & (1 << 5)) ? "X" : "",
  689. COND(opcode),
  690. (int) (opcode >> 16) & 0xf,
  691. (int) (opcode >> 0) & 0xf,
  692. (int) (opcode >> 8) & 0xf);
  693. return ERROR_OK;
  694. }
  695. if ((opcode & 0x01f00000) == 0x01400000) {
  696. sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d",
  697. (opcode & (1 << 6)) ? 'S' : 'A',
  698. (opcode & (1 << 5)) ? "X" : "",
  699. COND(opcode),
  700. (int) (opcode >> 12) & 0xf,
  701. (int) (opcode >> 16) & 0xf,
  702. (int) (opcode >> 0) & 0xf,
  703. (int) (opcode >> 8) & 0xf);
  704. return ERROR_OK;
  705. }
  706. if ((opcode & 0x01f00000) == 0x01500000) {
  707. unsigned rn = (opcode >> 12) & 0xf;
  708. switch (opcode & 0xc0) {
  709. case 3:
  710. if (rn == 0xf)
  711. goto undef;
  712. /* FALL THROUGH */
  713. case 0:
  714. break;
  715. default:
  716. goto undef;
  717. }
  718. if (rn != 0xf)
  719. sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d",
  720. (opcode & (1 << 6)) ? 'S' : 'A',
  721. (opcode & (1 << 5)) ? "R" : "",
  722. COND(opcode),
  723. (int) (opcode >> 16) & 0xf,
  724. (int) (opcode >> 0) & 0xf,
  725. (int) (opcode >> 8) & 0xf,
  726. rn);
  727. else
  728. sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d",
  729. (opcode & (1 << 5)) ? "R" : "",
  730. COND(opcode),
  731. (int) (opcode >> 16) & 0xf,
  732. (int) (opcode >> 0) & 0xf,
  733. (int) (opcode >> 8) & 0xf);
  734. return ERROR_OK;
  735. }
  736. /* simple matches against the remaining decode bits */
  737. switch (opcode & 0x01f000f0) {
  738. case 0x00a00030:
  739. case 0x00e00030:
  740. /* parallel halfword saturate */
  741. sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d",
  742. (opcode & (1 << 22)) ? 'U' : 'S',
  743. COND(opcode),
  744. (int) (opcode >> 12) & 0xf,
  745. (int) (opcode >> 16) & 0xf,
  746. (int) (opcode >> 0) & 0xf);
  747. return ERROR_OK;
  748. case 0x00b00030:
  749. mnemonic = "REV";
  750. break;
  751. case 0x00b000b0:
  752. mnemonic = "REV16";
  753. break;
  754. case 0x00f000b0:
  755. mnemonic = "REVSH";
  756. break;
  757. case 0x008000b0:
  758. /* select bytes */
  759. sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode),
  760. (int) (opcode >> 12) & 0xf,
  761. (int) (opcode >> 16) & 0xf,
  762. (int) (opcode >> 0) & 0xf);
  763. return ERROR_OK;
  764. case 0x01800010:
  765. /* unsigned sum of absolute differences */
  766. if (((opcode >> 12) & 0xf) == 0xf)
  767. sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode),
  768. (int) (opcode >> 16) & 0xf,
  769. (int) (opcode >> 0) & 0xf,
  770. (int) (opcode >> 8) & 0xf);
  771. else
  772. sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode),
  773. (int) (opcode >> 16) & 0xf,
  774. (int) (opcode >> 0) & 0xf,
  775. (int) (opcode >> 8) & 0xf,
  776. (int) (opcode >> 12) & 0xf);
  777. return ERROR_OK;
  778. }
  779. if (mnemonic) {
  780. unsigned rm = (opcode >> 0) & 0xf;
  781. unsigned rd = (opcode >> 12) & 0xf;
  782. sprintf(cp, "%s%s\tr%d, r%d", mnemonic, COND(opcode), rm, rd);
  783. return ERROR_OK;
  784. }
  785. undef:
  786. /* these opcodes might be used someday */
  787. sprintf(cp, "UNDEFINED");
  788. return ERROR_OK;
  789. }
  790. /* Miscellaneous load/store instructions */
  791. static int evaluate_misc_load_store(uint32_t opcode,
  792. uint32_t address, struct arm_instruction *instruction)
  793. {
  794. uint8_t P, U, I, W, L, S, H;
  795. uint8_t Rn, Rd;
  796. char *operation; /* "LDR" or "STR" */
  797. char *suffix; /* "H", "SB", "SH", "D" */
  798. char offset[32];
  799. /* examine flags */
  800. P = (opcode & 0x01000000) >> 24;
  801. U = (opcode & 0x00800000) >> 23;
  802. I = (opcode & 0x00400000) >> 22;
  803. W = (opcode & 0x00200000) >> 21;
  804. L = (opcode & 0x00100000) >> 20;
  805. S = (opcode & 0x00000040) >> 6;
  806. H = (opcode & 0x00000020) >> 5;
  807. /* target register */
  808. Rd = (opcode & 0xf000) >> 12;
  809. /* base register */
  810. Rn = (opcode & 0xf0000) >> 16;
  811. instruction->info.load_store.Rd = Rd;
  812. instruction->info.load_store.Rn = Rn;
  813. instruction->info.load_store.U = U;
  814. /* determine instruction type and suffix */
  815. if (S) /* signed */
  816. {
  817. if (L) /* load */
  818. {
  819. if (H)
  820. {
  821. operation = "LDR";
  822. instruction->type = ARM_LDRSH;
  823. suffix = "SH";
  824. }
  825. else
  826. {
  827. operation = "LDR";
  828. instruction->type = ARM_LDRSB;
  829. suffix = "SB";
  830. }
  831. }
  832. else /* there are no signed stores, so this is used to encode double-register load/stores */
  833. {
  834. suffix = "D";
  835. if (H)
  836. {
  837. operation = "STR";
  838. instruction->type = ARM_STRD;
  839. }
  840. else
  841. {
  842. operation = "LDR";
  843. instruction->type = ARM_LDRD;
  844. }
  845. }
  846. }
  847. else /* unsigned */
  848. {
  849. suffix = "H";
  850. if (L) /* load */
  851. {
  852. operation = "LDR";
  853. instruction->type = ARM_LDRH;
  854. }
  855. else /* store */
  856. {
  857. operation = "STR";
  858. instruction->type = ARM_STRH;
  859. }
  860. }
  861. if (I) /* Immediate offset/index (#+-<offset_8>)*/
  862. {
  863. uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
  864. snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
  865. instruction->info.load_store.offset_mode = 0;
  866. instruction->info.load_store.offset.offset = offset_8;
  867. }
  868. else /* Register offset/index (+-<Rm>) */
  869. {
  870. uint8_t Rm;
  871. Rm = (opcode & 0xf);
  872. snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
  873. instruction->info.load_store.offset_mode = 1;
  874. instruction->info.load_store.offset.reg.Rm = Rm;
  875. instruction->info.load_store.offset.reg.shift = 0x0;
  876. instruction->info.load_store.offset.reg.shift_imm = 0x0;
  877. }
  878. if (P == 1)
  879. {
  880. if (W == 0) /* offset */
  881. {
  882. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
  883. address, opcode, operation, COND(opcode), suffix,
  884. Rd, Rn, offset);
  885. instruction->info.load_store.index_mode = 0;
  886. }
  887. else /* pre-indexed */
  888. {
  889. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
  890. address, opcode, operation, COND(opcode), suffix,
  891. Rd, Rn, offset);
  892. instruction->info.load_store.index_mode = 1;
  893. }
  894. }
  895. else /* post-indexed */
  896. {
  897. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
  898. address, opcode, operation, COND(opcode), suffix,
  899. Rd, Rn, offset);
  900. instruction->info.load_store.index_mode = 2;
  901. }
  902. return ERROR_OK;
  903. }
  904. /* Load/store multiples instructions */
  905. static int evaluate_ldm_stm(uint32_t opcode,
  906. uint32_t address, struct arm_instruction *instruction)
  907. {
  908. uint8_t P, U, S, W, L, Rn;
  909. uint32_t register_list;
  910. char *addressing_mode;
  911. char *mnemonic;
  912. char reg_list[69];
  913. char *reg_list_p;
  914. int i;
  915. int first_reg = 1;
  916. P = (opcode & 0x01000000) >> 24;
  917. U = (opcode & 0x00800000) >> 23;
  918. S = (opcode & 0x00400000) >> 22;
  919. W = (opcode & 0x00200000) >> 21;
  920. L = (opcode & 0x00100000) >> 20;
  921. register_list = (opcode & 0xffff);
  922. Rn = (opcode & 0xf0000) >> 16;
  923. instruction->info.load_store_multiple.Rn = Rn;
  924. instruction->info.load_store_multiple.register_list = register_list;
  925. instruction->info.load_store_multiple.S = S;
  926. instruction->info.load_store_multiple.W = W;
  927. if (L)
  928. {
  929. instruction->type = ARM_LDM;
  930. mnemonic = "LDM";
  931. }
  932. else
  933. {
  934. instruction->type = ARM_STM;
  935. mnemonic = "STM";
  936. }
  937. if (P)
  938. {
  939. if (U)
  940. {
  941. instruction->info.load_store_multiple.addressing_mode = 1;
  942. addressing_mode = "IB";
  943. }
  944. else
  945. {
  946. instruction->info.load_store_multiple.addressing_mode = 3;
  947. addressing_mode = "DB";
  948. }
  949. }
  950. else
  951. {
  952. if (U)
  953. {
  954. instruction->info.load_store_multiple.addressing_mode = 0;
  955. /* "IA" is the default in UAL syntax */
  956. addressing_mode = "";
  957. }
  958. else
  959. {
  960. instruction->info.load_store_multiple.addressing_mode = 2;
  961. addressing_mode = "DA";
  962. }
  963. }
  964. reg_list_p = reg_list;
  965. for (i = 0; i <= 15; i++)
  966. {
  967. if ((register_list >> i) & 1)
  968. {
  969. if (first_reg)
  970. {
  971. first_reg = 0;
  972. reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), "r%i", i);
  973. }
  974. else
  975. {
  976. reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), ", r%i", i);
  977. }
  978. }
  979. }
  980. snprintf(instruction->text, 128,
  981. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
  982. "\t%s%s%s r%i%s, {%s}%s",
  983. address, opcode,
  984. mnemonic, addressing_mode, COND(opcode),
  985. Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
  986. return ERROR_OK;
  987. }
  988. /* Multiplies, extra load/stores */
  989. static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
  990. uint32_t address, struct arm_instruction *instruction)
  991. {
  992. /* Multiply (accumulate) (long) and Swap/swap byte */
  993. if ((opcode & 0x000000f0) == 0x00000090)
  994. {
  995. /* Multiply (accumulate) */
  996. if ((opcode & 0x0f800000) == 0x00000000)
  997. {
  998. uint8_t Rm, Rs, Rn, Rd, S;
  999. Rm = opcode & 0xf;
  1000. Rs = (opcode & 0xf00) >> 8;
  1001. Rn = (opcode & 0xf000) >> 12;
  1002. Rd = (opcode & 0xf0000) >> 16;
  1003. S = (opcode & 0x00100000) >> 20;
  1004. /* examine A bit (accumulate) */
  1005. if (opcode & 0x00200000)
  1006. {
  1007. instruction->type = ARM_MLA;
  1008. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
  1009. address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
  1010. }
  1011. else
  1012. {
  1013. instruction->type = ARM_MUL;
  1014. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
  1015. address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
  1016. }
  1017. return ERROR_OK;
  1018. }
  1019. /* Multiply (accumulate) long */
  1020. if ((opcode & 0x0f800000) == 0x00800000)
  1021. {
  1022. char* mnemonic = NULL;
  1023. uint8_t Rm, Rs, RdHi, RdLow, S;
  1024. Rm = opcode & 0xf;
  1025. Rs = (opcode & 0xf00) >> 8;
  1026. RdHi = (opcode & 0xf000) >> 12;
  1027. RdLow = (opcode & 0xf0000) >> 16;
  1028. S = (opcode & 0x00100000) >> 20;
  1029. switch ((opcode & 0x00600000) >> 21)
  1030. {
  1031. case 0x0:
  1032. instruction->type = ARM_UMULL;
  1033. mnemonic = "UMULL";
  1034. break;
  1035. case 0x1:
  1036. instruction->type = ARM_UMLAL;
  1037. mnemonic = "UMLAL";
  1038. break;
  1039. case 0x2:
  1040. instruction->type = ARM_SMULL;
  1041. mnemonic = "SMULL";
  1042. break;
  1043. case 0x3:
  1044. instruction->type = ARM_SMLAL;
  1045. mnemonic = "SMLAL";
  1046. break;
  1047. }
  1048. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
  1049. address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
  1050. RdLow, RdHi, Rm, Rs);
  1051. return ERROR_OK;
  1052. }
  1053. /* Swap/swap byte */
  1054. if ((opcode & 0x0f800000) == 0x01000000)
  1055. {
  1056. uint8_t Rm, Rd, Rn;
  1057. Rm = opcode & 0xf;
  1058. Rd = (opcode & 0xf000) >> 12;
  1059. Rn = (opcode & 0xf0000) >> 16;
  1060. /* examine B flag */
  1061. instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
  1062. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
  1063. address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
  1064. return ERROR_OK;
  1065. }
  1066. }
  1067. return evaluate_misc_load_store(opcode, address, instruction);
  1068. }
  1069. static int evaluate_mrs_msr(uint32_t opcode,
  1070. uint32_t address, struct arm_instruction *instruction)
  1071. {
  1072. int R = (opcode & 0x00400000) >> 22;
  1073. char *PSR = (R) ? "SPSR" : "CPSR";
  1074. /* Move register to status register (MSR) */
  1075. if (opcode & 0x00200000)
  1076. {
  1077. instruction->type = ARM_MSR;
  1078. /* immediate variant */
  1079. if (opcode & 0x02000000)
  1080. {
  1081. uint8_t immediate = (opcode & 0xff);
  1082. uint8_t rotate = (opcode & 0xf00);
  1083. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 ,
  1084. address, opcode, COND(opcode), PSR,
  1085. (opcode & 0x10000) ? "c" : "",
  1086. (opcode & 0x20000) ? "x" : "",
  1087. (opcode & 0x40000) ? "s" : "",
  1088. (opcode & 0x80000) ? "f" : "",
  1089. ror(immediate, (rotate * 2))
  1090. );
  1091. }
  1092. else /* register variant */
  1093. {
  1094. uint8_t Rm = opcode & 0xf;
  1095. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
  1096. address, opcode, COND(opcode), PSR,
  1097. (opcode & 0x10000) ? "c" : "",
  1098. (opcode & 0x20000) ? "x" : "",
  1099. (opcode & 0x40000) ? "s" : "",
  1100. (opcode & 0x80000) ? "f" : "",
  1101. Rm
  1102. );
  1103. }
  1104. }
  1105. else /* Move status register to register (MRS) */
  1106. {
  1107. uint8_t Rd;
  1108. instruction->type = ARM_MRS;
  1109. Rd = (opcode & 0x0000f000) >> 12;
  1110. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
  1111. address, opcode, COND(opcode), Rd, PSR);
  1112. }
  1113. return ERROR_OK;
  1114. }
  1115. /* Miscellaneous instructions */
  1116. static int evaluate_misc_instr(uint32_t opcode,
  1117. uint32_t address, struct arm_instruction *instruction)
  1118. {
  1119. /* MRS/MSR */
  1120. if ((opcode & 0x000000f0) == 0x00000000)
  1121. {
  1122. evaluate_mrs_msr(opcode, address, instruction);
  1123. }
  1124. /* BX */
  1125. if ((opcode & 0x006000f0) == 0x00200010)
  1126. {
  1127. uint8_t Rm;
  1128. instruction->type = ARM_BX;
  1129. Rm = opcode & 0xf;
  1130. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
  1131. address, opcode, COND(opcode), Rm);
  1132. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  1133. instruction->info.b_bl_bx_blx.target_address = -1;
  1134. }
  1135. /* BXJ - "Jazelle" support (ARMv5-J) */
  1136. if ((opcode & 0x006000f0) == 0x00200020)
  1137. {
  1138. uint8_t Rm;
  1139. instruction->type = ARM_BX;
  1140. Rm = opcode & 0xf;
  1141. snprintf(instruction->text, 128,
  1142. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i",
  1143. address, opcode, COND(opcode), Rm);
  1144. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  1145. instruction->info.b_bl_bx_blx.target_address = -1;
  1146. }
  1147. /* CLZ */
  1148. if ((opcode & 0x006000f0) == 0x00600010)
  1149. {
  1150. uint8_t Rm, Rd;
  1151. instruction->type = ARM_CLZ;
  1152. Rm = opcode & 0xf;
  1153. Rd = (opcode & 0xf000) >> 12;
  1154. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
  1155. address, opcode, COND(opcode), Rd, Rm);
  1156. }
  1157. /* BLX(2) */
  1158. if ((opcode & 0x006000f0) == 0x00200030)
  1159. {
  1160. uint8_t Rm;
  1161. instruction->type = ARM_BLX;
  1162. Rm = opcode & 0xf;
  1163. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
  1164. address, opcode, COND(opcode), Rm);
  1165. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  1166. instruction->info.b_bl_bx_blx.target_address = -1;
  1167. }
  1168. /* Enhanced DSP add/subtracts */
  1169. if ((opcode & 0x0000000f0) == 0x00000050)
  1170. {
  1171. uint8_t Rm, Rd, Rn;
  1172. char *mnemonic = NULL;
  1173. Rm = opcode & 0xf;
  1174. Rd = (opcode & 0xf000) >> 12;
  1175. Rn = (opcode & 0xf0000) >> 16;
  1176. switch ((opcode & 0x00600000) >> 21)
  1177. {
  1178. case 0x0:
  1179. instruction->type = ARM_QADD;
  1180. mnemonic = "QADD";
  1181. break;
  1182. case 0x1:
  1183. instruction->type = ARM_QSUB;
  1184. mnemonic = "QSUB";
  1185. break;
  1186. case 0x2:
  1187. instruction->type = ARM_QDADD;
  1188. mnemonic = "QDADD";
  1189. break;
  1190. case 0x3:
  1191. instruction->type = ARM_QDSUB;
  1192. mnemonic = "QDSUB";
  1193. break;
  1194. }
  1195. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
  1196. address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
  1197. }
  1198. /* Software breakpoints */
  1199. if ((opcode & 0x0000000f0) == 0x00000070)
  1200. {
  1201. uint32_t immediate;
  1202. instruction->type = ARM_BKPT;
  1203. immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
  1204. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
  1205. address, opcode, immediate);
  1206. }
  1207. /* Enhanced DSP multiplies */
  1208. if ((opcode & 0x000000090) == 0x00000080)
  1209. {
  1210. int x = (opcode & 0x20) >> 5;
  1211. int y = (opcode & 0x40) >> 6;
  1212. /* SMLA < x><y> */
  1213. if ((opcode & 0x00600000) == 0x00000000)
  1214. {
  1215. uint8_t Rd, Rm, Rs, Rn;
  1216. instruction->type = ARM_SMLAxy;
  1217. Rd = (opcode & 0xf0000) >> 16;
  1218. Rm = (opcode & 0xf);
  1219. Rs = (opcode & 0xf00) >> 8;
  1220. Rn = (opcode & 0xf000) >> 12;
  1221. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
  1222. address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
  1223. Rd, Rm, Rs, Rn);
  1224. }
  1225. /* SMLAL < x><y> */
  1226. if ((opcode & 0x00600000) == 0x00400000)
  1227. {
  1228. uint8_t RdLow, RdHi, Rm, Rs;
  1229. instruction->type = ARM_SMLAxy;
  1230. RdHi = (opcode & 0xf0000) >> 16;
  1231. RdLow = (opcode & 0xf000) >> 12;
  1232. Rm = (opcode & 0xf);
  1233. Rs = (opcode & 0xf00) >> 8;
  1234. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
  1235. address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
  1236. RdLow, RdHi, Rm, Rs);
  1237. }
  1238. /* SMLAW < y> */
  1239. if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
  1240. {
  1241. uint8_t Rd, Rm, Rs, Rn;
  1242. instruction->type = ARM_SMLAWy;
  1243. Rd = (opcode & 0xf0000) >> 16;
  1244. Rm = (opcode & 0xf);
  1245. Rs = (opcode & 0xf00) >> 8;
  1246. Rn = (opcode & 0xf000) >> 12;
  1247. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
  1248. address, opcode, (y) ? "T" : "B", COND(opcode),
  1249. Rd, Rm, Rs, Rn);
  1250. }
  1251. /* SMUL < x><y> */
  1252. if ((opcode & 0x00600000) == 0x00300000)
  1253. {
  1254. uint8_t Rd, Rm, Rs;
  1255. instruction->type = ARM_SMULxy;
  1256. Rd = (opcode & 0xf0000) >> 16;
  1257. Rm = (opcode & 0xf);
  1258. Rs = (opcode & 0xf00) >> 8;
  1259. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
  1260. address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
  1261. Rd, Rm, Rs);
  1262. }
  1263. /* SMULW < y> */
  1264. if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
  1265. {
  1266. uint8_t Rd, Rm, Rs;
  1267. instruction->type = ARM_SMULWy;
  1268. Rd = (opcode & 0xf0000) >> 16;
  1269. Rm = (opcode & 0xf);
  1270. Rs = (opcode & 0xf00) >> 8;
  1271. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
  1272. address, opcode, (y) ? "T" : "B", COND(opcode),
  1273. Rd, Rm, Rs);
  1274. }
  1275. }
  1276. return ERROR_OK;
  1277. }
  1278. static int evaluate_data_proc(uint32_t opcode,
  1279. uint32_t address, struct arm_instruction *instruction)
  1280. {
  1281. uint8_t I, op, S, Rn, Rd;
  1282. char *mnemonic = NULL;
  1283. char shifter_operand[32];
  1284. I = (opcode & 0x02000000) >> 25;
  1285. op = (opcode & 0x01e00000) >> 21;
  1286. S = (opcode & 0x00100000) >> 20;
  1287. Rd = (opcode & 0xf000) >> 12;
  1288. Rn = (opcode & 0xf0000) >> 16;
  1289. instruction->info.data_proc.Rd = Rd;
  1290. instruction->info.data_proc.Rn = Rn;
  1291. instruction->info.data_proc.S = S;
  1292. switch (op)
  1293. {
  1294. case 0x0:
  1295. instruction->type = ARM_AND;
  1296. mnemonic = "AND";
  1297. break;
  1298. case 0x1:
  1299. instruction->type = ARM_EOR;
  1300. mnemonic = "EOR";
  1301. break;
  1302. case 0x2:
  1303. instruction->type = ARM_SUB;
  1304. mnemonic = "SUB";
  1305. break;
  1306. case 0x3:
  1307. instruction->type = ARM_RSB;
  1308. mnemonic = "RSB";
  1309. break;
  1310. case 0x4:
  1311. instruction->type = ARM_ADD;
  1312. mnemonic = "ADD";
  1313. break;
  1314. case 0x5:
  1315. instruction->type = ARM_ADC;
  1316. mnemonic = "ADC";
  1317. break;
  1318. case 0x6:
  1319. instruction->type = ARM_SBC;
  1320. mnemonic = "SBC";
  1321. break;
  1322. case 0x7:
  1323. instruction->type = ARM_RSC;
  1324. mnemonic = "RSC";
  1325. break;
  1326. case 0x8:
  1327. instruction->type = ARM_TST;
  1328. mnemonic = "TST";
  1329. break;
  1330. case 0x9:
  1331. instruction->type = ARM_TEQ;
  1332. mnemonic = "TEQ";
  1333. break;
  1334. case 0xa:
  1335. instruction->type = ARM_CMP;
  1336. mnemonic = "CMP";
  1337. break;
  1338. case 0xb:
  1339. instruction->type = ARM_CMN;
  1340. mnemonic = "CMN";
  1341. break;
  1342. case 0xc:
  1343. instruction->type = ARM_ORR;
  1344. mnemonic = "ORR";
  1345. break;
  1346. case 0xd:
  1347. instruction->type = ARM_MOV;
  1348. mnemonic = "MOV";
  1349. break;
  1350. case 0xe:
  1351. instruction->type = ARM_BIC;
  1352. mnemonic = "BIC";
  1353. break;
  1354. case 0xf:
  1355. instruction->type = ARM_MVN;
  1356. mnemonic = "MVN";
  1357. break;
  1358. }
  1359. if (I) /* immediate shifter operand (#<immediate>)*/
  1360. {
  1361. uint8_t immed_8 = opcode & 0xff;
  1362. uint8_t rotate_imm = (opcode & 0xf00) >> 8;
  1363. uint32_t immediate;
  1364. immediate = ror(immed_8, rotate_imm * 2);
  1365. snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
  1366. instruction->info.data_proc.variant = 0;
  1367. instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
  1368. }
  1369. else /* register-based shifter operand */
  1370. {
  1371. uint8_t shift, Rm;
  1372. shift = (opcode & 0x60) >> 5;
  1373. Rm = (opcode & 0xf);
  1374. if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
  1375. {
  1376. uint8_t shift_imm;
  1377. shift_imm = (opcode & 0xf80) >> 7;
  1378. instruction->info.data_proc.variant = 1;
  1379. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
  1380. instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
  1381. instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
  1382. /* LSR encodes a shift by 32 bit as 0x0 */
  1383. if ((shift == 0x1) && (shift_imm == 0x0))
  1384. shift_imm = 0x20;
  1385. /* ASR encodes a shift by 32 bit as 0x0 */
  1386. if ((shift == 0x2) && (shift_imm == 0x0))
  1387. shift_imm = 0x20;
  1388. /* ROR by 32 bit is actually a RRX */
  1389. if ((shift == 0x3) && (shift_imm == 0x0))
  1390. shift = 0x4;
  1391. if ((shift_imm == 0x0) && (shift == 0x0))
  1392. {
  1393. snprintf(shifter_operand, 32, "r%i", Rm);
  1394. }
  1395. else
  1396. {
  1397. if (shift == 0x0) /* LSL */
  1398. {
  1399. snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm);
  1400. }
  1401. else if (shift == 0x1) /* LSR */
  1402. {
  1403. snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
  1404. }
  1405. else if (shift == 0x2) /* ASR */
  1406. {
  1407. snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
  1408. }
  1409. else if (shift == 0x3) /* ROR */
  1410. {
  1411. snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
  1412. }
  1413. else if (shift == 0x4) /* RRX */
  1414. {
  1415. snprintf(shifter_operand, 32, "r%i, RRX", Rm);
  1416. }
  1417. }
  1418. }
  1419. else /* Register shifts ("<Rm>, <shift> <Rs>") */
  1420. {
  1421. uint8_t Rs = (opcode & 0xf00) >> 8;
  1422. instruction->info.data_proc.variant = 2;
  1423. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
  1424. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
  1425. instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
  1426. if (shift == 0x0) /* LSL */
  1427. {
  1428. snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
  1429. }
  1430. else if (shift == 0x1) /* LSR */
  1431. {
  1432. snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
  1433. }
  1434. else if (shift == 0x2) /* ASR */
  1435. {
  1436. snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
  1437. }
  1438. else if (shift == 0x3) /* ROR */
  1439. {
  1440. snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
  1441. }
  1442. }
  1443. }
  1444. if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
  1445. {
  1446. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
  1447. address, opcode, mnemonic, COND(opcode),
  1448. (S) ? "S" : "", Rd, Rn, shifter_operand);
  1449. }
  1450. else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
  1451. {
  1452. if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */
  1453. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",address, opcode);
  1454. else
  1455. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
  1456. address, opcode, mnemonic, COND(opcode),
  1457. (S) ? "S" : "", Rd, shifter_operand);
  1458. }
  1459. else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
  1460. {
  1461. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
  1462. address, opcode, mnemonic, COND(opcode),
  1463. Rn, shifter_operand);
  1464. }
  1465. return ERROR_OK;
  1466. }
  1467. int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
  1468. struct arm_instruction *instruction)
  1469. {
  1470. /* clear fields, to avoid confusion */
  1471. memset(instruction, 0, sizeof(struct arm_instruction));
  1472. instruction->opcode = opcode;
  1473. instruction->instruction_size = 4;
  1474. /* catch opcodes with condition field [31:28] = b1111 */
  1475. if ((opcode & 0xf0000000) == 0xf0000000)
  1476. {
  1477. /* Undefined instruction (or ARMv5E cache preload PLD) */
  1478. if ((opcode & 0x08000000) == 0x00000000)
  1479. return evaluate_pld(opcode, address, instruction);
  1480. /* Undefined instruction (or ARMv6+ SRS/RFE) */
  1481. if ((opcode & 0x0e000000) == 0x08000000)
  1482. return evaluate_srs(opcode, address, instruction);
  1483. /* Branch and branch with link and change to Thumb */
  1484. if ((opcode & 0x0e000000) == 0x0a000000)
  1485. return evaluate_blx_imm(opcode, address, instruction);
  1486. /* Extended coprocessor opcode space (ARMv5 and higher)*/
  1487. /* Coprocessor load/store and double register transfers */
  1488. if ((opcode & 0x0e000000) == 0x0c000000)
  1489. return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
  1490. /* Coprocessor data processing */
  1491. if ((opcode & 0x0f000100) == 0x0c000000)
  1492. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1493. /* Coprocessor register transfers */
  1494. if ((opcode & 0x0f000010) == 0x0c000010)
  1495. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1496. /* Undefined instruction */
  1497. if ((opcode & 0x0f000000) == 0x0f000000)
  1498. {
  1499. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1500. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
  1501. return ERROR_OK;
  1502. }
  1503. }
  1504. /* catch opcodes with [27:25] = b000 */
  1505. if ((opcode & 0x0e000000) == 0x00000000)
  1506. {
  1507. /* Multiplies, extra load/stores */
  1508. if ((opcode & 0x00000090) == 0x00000090)
  1509. return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
  1510. /* Miscellaneous instructions */
  1511. if ((opcode & 0x0f900000) == 0x01000000)
  1512. return evaluate_misc_instr(opcode, address, instruction);
  1513. return evaluate_data_proc(opcode, address, instruction);
  1514. }
  1515. /* catch opcodes with [27:25] = b001 */
  1516. if ((opcode & 0x0e000000) == 0x02000000)
  1517. {
  1518. /* Undefined instruction */
  1519. if ((opcode & 0x0fb00000) == 0x03000000)
  1520. {
  1521. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1522. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
  1523. return ERROR_OK;
  1524. }
  1525. /* Move immediate to status register */
  1526. if ((opcode & 0x0fb00000) == 0x03200000)
  1527. return evaluate_mrs_msr(opcode, address, instruction);
  1528. return evaluate_data_proc(opcode, address, instruction);
  1529. }
  1530. /* catch opcodes with [27:25] = b010 */
  1531. if ((opcode & 0x0e000000) == 0x04000000)
  1532. {
  1533. /* Load/store immediate offset */
  1534. return evaluate_load_store(opcode, address, instruction);
  1535. }
  1536. /* catch opcodes with [27:25] = b011 */
  1537. if ((opcode & 0x0e000000) == 0x06000000)
  1538. {
  1539. /* Load/store register offset */
  1540. if ((opcode & 0x00000010) == 0x00000000)
  1541. return evaluate_load_store(opcode, address, instruction);
  1542. /* Architecturally Undefined instruction
  1543. * ... don't expect these to ever be used
  1544. */
  1545. if ((opcode & 0x07f000f0) == 0x07f000f0)
  1546. {
  1547. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1548. snprintf(instruction->text, 128,
  1549. "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF",
  1550. address, opcode);
  1551. return ERROR_OK;
  1552. }
  1553. /* "media" instructions */
  1554. return evaluate_media(opcode, address, instruction);
  1555. }
  1556. /* catch opcodes with [27:25] = b100 */
  1557. if ((opcode & 0x0e000000) == 0x08000000)
  1558. {
  1559. /* Load/store multiple */
  1560. return evaluate_ldm_stm(opcode, address, instruction);
  1561. }
  1562. /* catch opcodes with [27:25] = b101 */
  1563. if ((opcode & 0x0e000000) == 0x0a000000)
  1564. {
  1565. /* Branch and branch with link */
  1566. return evaluate_b_bl(opcode, address, instruction);
  1567. }
  1568. /* catch opcodes with [27:25] = b110 */
  1569. if ((opcode & 0x0e000000) == 0x0c000000)
  1570. {
  1571. /* Coprocessor load/store and double register transfers */
  1572. return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
  1573. }
  1574. /* catch opcodes with [27:25] = b111 */
  1575. if ((opcode & 0x0e000000) == 0x0e000000)
  1576. {
  1577. /* Software interrupt */
  1578. if ((opcode & 0x0f000000) == 0x0f000000)
  1579. return evaluate_swi(opcode, address, instruction);
  1580. /* Coprocessor data processing */
  1581. if ((opcode & 0x0f000010) == 0x0e000000)
  1582. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1583. /* Coprocessor register transfers */
  1584. if ((opcode & 0x0f000010) == 0x0e000010)
  1585. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1586. }
  1587. LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
  1588. (unsigned) opcode);
  1589. return -1;
  1590. }
  1591. static int evaluate_b_bl_blx_thumb(uint16_t opcode,
  1592. uint32_t address, struct arm_instruction *instruction)
  1593. {
  1594. uint32_t offset = opcode & 0x7ff;
  1595. uint32_t opc = (opcode >> 11) & 0x3;
  1596. uint32_t target_address;
  1597. char *mnemonic = NULL;
  1598. /* sign extend 11-bit offset */
  1599. if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
  1600. offset = 0xfffff800 | offset;
  1601. target_address = address + 4 + (offset << 1);
  1602. switch (opc)
  1603. {
  1604. /* unconditional branch */
  1605. case 0:
  1606. instruction->type = ARM_B;
  1607. mnemonic = "B";
  1608. break;
  1609. /* BLX suffix */
  1610. case 1:
  1611. instruction->type = ARM_BLX;
  1612. mnemonic = "BLX";
  1613. target_address &= 0xfffffffc;
  1614. break;
  1615. /* BL/BLX prefix */
  1616. case 2:
  1617. instruction->type = ARM_UNKNOWN_INSTUCTION;
  1618. mnemonic = "prefix";
  1619. target_address = offset << 12;
  1620. break;
  1621. /* BL suffix */
  1622. case 3:
  1623. instruction->type = ARM_BL;
  1624. mnemonic = "BL";
  1625. break;
  1626. }
  1627. /* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
  1628. * these are effectively 32-bit instructions even in Thumb1. For
  1629. * disassembly, it's simplest to always use the Thumb2 decoder.
  1630. *
  1631. * But some cores will evidently handle them as two instructions,
  1632. * where exceptions may occur between the two. The ETMv3.2+ ID
  1633. * register has a bit which exposes this behavior.
  1634. */
  1635. snprintf(instruction->text, 128,
  1636. "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%#8.8" PRIx32,
  1637. address, opcode, mnemonic, target_address);
  1638. instruction->info.b_bl_bx_blx.reg_operand = -1;
  1639. instruction->info.b_bl_bx_blx.target_address = target_address;
  1640. return ERROR_OK;
  1641. }
  1642. static int evaluate_add_sub_thumb(uint16_t opcode,
  1643. uint32_t address, struct arm_instruction *instruction)
  1644. {
  1645. uint8_t Rd = (opcode >> 0) & 0x7;
  1646. uint8_t Rn = (opcode >> 3) & 0x7;
  1647. uint8_t Rm_imm = (opcode >> 6) & 0x7;
  1648. uint32_t opc = opcode & (1 << 9);
  1649. uint32_t reg_imm = opcode & (1 << 10);
  1650. char *mnemonic;
  1651. if (opc)
  1652. {
  1653. instruction->type = ARM_SUB;
  1654. mnemonic = "SUBS";
  1655. }
  1656. else
  1657. {
  1658. /* REVISIT: if reg_imm == 0, display as "MOVS" */
  1659. instruction->type = ARM_ADD;
  1660. mnemonic = "ADDS";
  1661. }
  1662. instruction->info.data_proc.Rd = Rd;
  1663. instruction->info.data_proc.Rn = Rn;
  1664. instruction->info.data_proc.S = 1;
  1665. if (reg_imm)
  1666. {
  1667. instruction->info.data_proc.variant = 0; /*immediate*/
  1668. instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
  1669. snprintf(instruction->text, 128,
  1670. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d",
  1671. address, opcode, mnemonic, Rd, Rn, Rm_imm);
  1672. }
  1673. else
  1674. {
  1675. instruction->info.data_proc.variant = 1; /*immediate shift*/
  1676. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
  1677. snprintf(instruction->text, 128,
  1678. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i",
  1679. address, opcode, mnemonic, Rd, Rn, Rm_imm);
  1680. }
  1681. return ERROR_OK;
  1682. }
  1683. static int evaluate_shift_imm_thumb(uint16_t opcode,
  1684. uint32_t address, struct arm_instruction *instruction)
  1685. {
  1686. uint8_t Rd = (opcode >> 0) & 0x7;
  1687. uint8_t Rm = (opcode >> 3) & 0x7;
  1688. uint8_t imm = (opcode >> 6) & 0x1f;
  1689. uint8_t opc = (opcode >> 11) & 0x3;
  1690. char *mnemonic = NULL;
  1691. switch (opc)
  1692. {
  1693. case 0:
  1694. instruction->type = ARM_MOV;
  1695. mnemonic = "LSLS";
  1696. instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
  1697. break;
  1698. case 1:
  1699. instruction->type = ARM_MOV;
  1700. mnemonic = "LSRS";
  1701. instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
  1702. break;
  1703. case 2:
  1704. instruction->type = ARM_MOV;
  1705. mnemonic = "ASRS";
  1706. instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
  1707. break;
  1708. }
  1709. if ((imm == 0) && (opc != 0))
  1710. imm = 32;
  1711. instruction->info.data_proc.Rd = Rd;
  1712. instruction->info.data_proc.Rn = -1;
  1713. instruction->info.data_proc.S = 1;
  1714. instruction->info.data_proc.variant = 1; /*immediate_shift*/
  1715. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
  1716. instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
  1717. snprintf(instruction->text, 128,
  1718. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x" ,
  1719. address, opcode, mnemonic, Rd, Rm, imm);
  1720. return ERROR_OK;
  1721. }
  1722. static int evaluate_data_proc_imm_thumb(uint16_t opcode,
  1723. uint32_t address, struct arm_instruction *instruction)
  1724. {
  1725. uint8_t imm = opcode & 0xff;
  1726. uint8_t Rd = (opcode >> 8) & 0x7;
  1727. uint32_t opc = (opcode >> 11) & 0x3;
  1728. char *mnemonic = NULL;
  1729. instruction->info.data_proc.Rd = Rd;
  1730. instruction->info.data_proc.Rn = Rd;
  1731. instruction->info.data_proc.S = 1;
  1732. instruction->info.data_proc.variant = 0; /*immediate*/
  1733. instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
  1734. switch (opc)
  1735. {
  1736. case 0:
  1737. instruction->type = ARM_MOV;
  1738. mnemonic = "MOVS";
  1739. instruction->info.data_proc.Rn = -1;
  1740. break;
  1741. case 1:
  1742. instruction->type = ARM_CMP;
  1743. mnemonic = "CMP";
  1744. instruction->info.data_proc.Rd = -1;
  1745. break;
  1746. case 2:
  1747. instruction->type = ARM_ADD;
  1748. mnemonic = "ADDS";
  1749. break;
  1750. case 3:
  1751. instruction->type = ARM_SUB;
  1752. mnemonic = "SUBS";
  1753. break;
  1754. }
  1755. snprintf(instruction->text, 128,
  1756. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, #%#2.2x",
  1757. address, opcode, mnemonic, Rd, imm);
  1758. return ERROR_OK;
  1759. }
  1760. static int evaluate_data_proc_thumb(uint16_t opcode,
  1761. uint32_t address, struct arm_instruction *instruction)
  1762. {
  1763. uint8_t high_reg, op, Rm, Rd,H1,H2;
  1764. char *mnemonic = NULL;
  1765. bool nop = false;
  1766. high_reg = (opcode & 0x0400) >> 10;
  1767. op = (opcode & 0x03C0) >> 6;
  1768. Rd = (opcode & 0x0007);
  1769. Rm = (opcode & 0x0038) >> 3;
  1770. H1 = (opcode & 0x0080) >> 7;
  1771. H2 = (opcode & 0x0040) >> 6;
  1772. instruction->info.data_proc.Rd = Rd;
  1773. instruction->info.data_proc.Rn = Rd;
  1774. instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
  1775. instruction->info.data_proc.variant = 1 /*immediate shift*/;
  1776. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
  1777. if (high_reg)
  1778. {
  1779. Rd |= H1 << 3;
  1780. Rm |= H2 << 3;
  1781. op >>= 2;
  1782. switch (op)
  1783. {
  1784. case 0x0:
  1785. instruction->type = ARM_ADD;
  1786. mnemonic = "ADD";
  1787. break;
  1788. case 0x1:
  1789. instruction->type = ARM_CMP;
  1790. mnemonic = "CMP";
  1791. break;
  1792. case 0x2:
  1793. instruction->type = ARM_MOV;
  1794. mnemonic = "MOV";
  1795. if (Rd == Rm)
  1796. nop = true;
  1797. break;
  1798. case 0x3:
  1799. if ((opcode & 0x7) == 0x0)
  1800. {
  1801. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  1802. if (H1)
  1803. {
  1804. instruction->type = ARM_BLX;
  1805. snprintf(instruction->text, 128,
  1806. "0x%8.8" PRIx32
  1807. " 0x%4.4x \tBLX\tr%i",
  1808. address, opcode, Rm);
  1809. }
  1810. else
  1811. {
  1812. instruction->type = ARM_BX;
  1813. snprintf(instruction->text, 128,
  1814. "0x%8.8" PRIx32
  1815. " 0x%4.4x \tBX\tr%i",
  1816. address, opcode, Rm);
  1817. }
  1818. }
  1819. else
  1820. {
  1821. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1822. snprintf(instruction->text, 128,
  1823. "0x%8.8" PRIx32
  1824. " 0x%4.4x \t"
  1825. "UNDEFINED INSTRUCTION",
  1826. address, opcode);
  1827. }
  1828. return ERROR_OK;
  1829. break;
  1830. }
  1831. }
  1832. else
  1833. {
  1834. switch (op)
  1835. {
  1836. case 0x0:
  1837. instruction->type = ARM_AND;
  1838. mnemonic = "ANDS";
  1839. break;
  1840. case 0x1:
  1841. instruction->type = ARM_EOR;
  1842. mnemonic = "EORS";
  1843. break;
  1844. case 0x2:
  1845. instruction->type = ARM_MOV;
  1846. mnemonic = "LSLS";
  1847. instruction->info.data_proc.variant = 2 /*register shift*/;
  1848. instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
  1849. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1850. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1851. break;
  1852. case 0x3:
  1853. instruction->type = ARM_MOV;
  1854. mnemonic = "LSRS";
  1855. instruction->info.data_proc.variant = 2 /*register shift*/;
  1856. instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
  1857. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1858. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1859. break;
  1860. case 0x4:
  1861. instruction->type = ARM_MOV;
  1862. mnemonic = "ASRS";
  1863. instruction->info.data_proc.variant = 2 /*register shift*/;
  1864. instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
  1865. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1866. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1867. break;
  1868. case 0x5:
  1869. instruction->type = ARM_ADC;
  1870. mnemonic = "ADCS";
  1871. break;
  1872. case 0x6:
  1873. instruction->type = ARM_SBC;
  1874. mnemonic = "SBCS";
  1875. break;
  1876. case 0x7:
  1877. instruction->type = ARM_MOV;
  1878. mnemonic = "RORS";
  1879. instruction->info.data_proc.variant = 2 /*register shift*/;
  1880. instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
  1881. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1882. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1883. break;
  1884. case 0x8:
  1885. instruction->type = ARM_TST;
  1886. mnemonic = "TST";
  1887. break;
  1888. case 0x9:
  1889. instruction->type = ARM_RSB;
  1890. mnemonic = "RSBS";
  1891. instruction->info.data_proc.variant = 0 /*immediate*/;
  1892. instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
  1893. instruction->info.data_proc.Rn = Rm;
  1894. break;
  1895. case 0xA:
  1896. instruction->type = ARM_CMP;
  1897. mnemonic = "CMP";
  1898. break;
  1899. case 0xB:
  1900. instruction->type = ARM_CMN;
  1901. mnemonic = "CMN";
  1902. break;
  1903. case 0xC:
  1904. instruction->type = ARM_ORR;
  1905. mnemonic = "ORRS";
  1906. break;
  1907. case 0xD:
  1908. instruction->type = ARM_MUL;
  1909. mnemonic = "MULS";
  1910. break;
  1911. case 0xE:
  1912. instruction->type = ARM_BIC;
  1913. mnemonic = "BICS";
  1914. break;
  1915. case 0xF:
  1916. instruction->type = ARM_MVN;
  1917. mnemonic = "MVNS";
  1918. break;
  1919. }
  1920. }
  1921. if (nop)
  1922. snprintf(instruction->text, 128,
  1923. "0x%8.8" PRIx32 " 0x%4.4x \tNOP\t\t\t"
  1924. "; (%s r%i, r%i)",
  1925. address, opcode, mnemonic, Rd, Rm);
  1926. else
  1927. snprintf(instruction->text, 128,
  1928. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i",
  1929. address, opcode, mnemonic, Rd, Rm);
  1930. return ERROR_OK;
  1931. }
  1932. /* PC-relative data addressing is word-aligned even with Thumb */
  1933. static inline uint32_t thumb_alignpc4(uint32_t addr)
  1934. {
  1935. return (addr + 4) & ~3;
  1936. }
  1937. static int evaluate_load_literal_thumb(uint16_t opcode,
  1938. uint32_t address, struct arm_instruction *instruction)
  1939. {
  1940. uint32_t immediate;
  1941. uint8_t Rd = (opcode >> 8) & 0x7;
  1942. instruction->type = ARM_LDR;
  1943. immediate = opcode & 0x000000ff;
  1944. immediate *= 4;
  1945. instruction->info.load_store.Rd = Rd;
  1946. instruction->info.load_store.Rn = 15 /*PC*/;
  1947. instruction->info.load_store.index_mode = 0; /*offset*/
  1948. instruction->info.load_store.offset_mode = 0; /*immediate*/
  1949. instruction->info.load_store.offset.offset = immediate;
  1950. snprintf(instruction->text, 128,
  1951. "0x%8.8" PRIx32 " 0x%4.4x \t"
  1952. "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
  1953. address, opcode, Rd, immediate,
  1954. thumb_alignpc4(address) + immediate);
  1955. return ERROR_OK;
  1956. }
  1957. static int evaluate_load_store_reg_thumb(uint16_t opcode,
  1958. uint32_t address, struct arm_instruction *instruction)
  1959. {
  1960. uint8_t Rd = (opcode >> 0) & 0x7;
  1961. uint8_t Rn = (opcode >> 3) & 0x7;
  1962. uint8_t Rm = (opcode >> 6) & 0x7;
  1963. uint8_t opc = (opcode >> 9) & 0x7;
  1964. char *mnemonic = NULL;
  1965. switch (opc)
  1966. {
  1967. case 0:
  1968. instruction->type = ARM_STR;
  1969. mnemonic = "STR";
  1970. break;
  1971. case 1:
  1972. instruction->type = ARM_STRH;
  1973. mnemonic = "STRH";
  1974. break;
  1975. case 2:
  1976. instruction->type = ARM_STRB;
  1977. mnemonic = "STRB";
  1978. break;
  1979. case 3:
  1980. instruction->type = ARM_LDRSB;
  1981. mnemonic = "LDRSB";
  1982. break;
  1983. case 4:
  1984. instruction->type = ARM_LDR;
  1985. mnemonic = "LDR";
  1986. break;
  1987. case 5:
  1988. instruction->type = ARM_LDRH;
  1989. mnemonic = "LDRH";
  1990. break;
  1991. case 6:
  1992. instruction->type = ARM_LDRB;
  1993. mnemonic = "LDRB";
  1994. break;
  1995. case 7:
  1996. instruction->type = ARM_LDRSH;
  1997. mnemonic = "LDRSH";
  1998. break;
  1999. }
  2000. snprintf(instruction->text, 128,
  2001. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [r%i, r%i]",
  2002. address, opcode, mnemonic, Rd, Rn, Rm);
  2003. instruction->info.load_store.Rd = Rd;
  2004. instruction->info.load_store.Rn = Rn;
  2005. instruction->info.load_store.index_mode = 0; /*offset*/
  2006. instruction->info.load_store.offset_mode = 1; /*register*/
  2007. instruction->info.load_store.offset.reg.Rm = Rm;
  2008. return ERROR_OK;
  2009. }
  2010. static int evaluate_load_store_imm_thumb(uint16_t opcode,
  2011. uint32_t address, struct arm_instruction *instruction)
  2012. {
  2013. uint32_t offset = (opcode >> 6) & 0x1f;
  2014. uint8_t Rd = (opcode >> 0) & 0x7;
  2015. uint8_t Rn = (opcode >> 3) & 0x7;
  2016. uint32_t L = opcode & (1 << 11);
  2017. uint32_t B = opcode & (1 << 12);
  2018. char *mnemonic;
  2019. char suffix = ' ';
  2020. uint32_t shift = 2;
  2021. if (L)
  2022. {
  2023. instruction->type = ARM_LDR;
  2024. mnemonic = "LDR";
  2025. }
  2026. else
  2027. {
  2028. instruction->type = ARM_STR;
  2029. mnemonic = "STR";
  2030. }
  2031. if ((opcode&0xF000) == 0x8000)
  2032. {
  2033. suffix = 'H';
  2034. shift = 1;
  2035. }
  2036. else if (B)
  2037. {
  2038. suffix = 'B';
  2039. shift = 0;
  2040. }
  2041. snprintf(instruction->text, 128,
  2042. "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
  2043. address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
  2044. instruction->info.load_store.Rd = Rd;
  2045. instruction->info.load_store.Rn = Rn;
  2046. instruction->info.load_store.index_mode = 0; /*offset*/
  2047. instruction->info.load_store.offset_mode = 0; /*immediate*/
  2048. instruction->info.load_store.offset.offset = offset << shift;
  2049. return ERROR_OK;
  2050. }
  2051. static int evaluate_load_store_stack_thumb(uint16_t opcode,
  2052. uint32_t address, struct arm_instruction *instruction)
  2053. {
  2054. uint32_t offset = opcode & 0xff;
  2055. uint8_t Rd = (opcode >> 8) & 0x7;
  2056. uint32_t L = opcode & (1 << 11);
  2057. char *mnemonic;
  2058. if (L)
  2059. {
  2060. instruction->type = ARM_LDR;
  2061. mnemonic = "LDR";
  2062. }
  2063. else
  2064. {
  2065. instruction->type = ARM_STR;
  2066. mnemonic = "STR";
  2067. }
  2068. snprintf(instruction->text, 128,
  2069. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" PRIx32 "]",
  2070. address, opcode, mnemonic, Rd, offset*4);
  2071. instruction->info.load_store.Rd = Rd;
  2072. instruction->info.load_store.Rn = 13 /*SP*/;
  2073. instruction->info.load_store.index_mode = 0; /*offset*/
  2074. instruction->info.load_store.offset_mode = 0; /*immediate*/
  2075. instruction->info.load_store.offset.offset = offset*4;
  2076. return ERROR_OK;
  2077. }
  2078. static int evaluate_add_sp_pc_thumb(uint16_t opcode,
  2079. uint32_t address, struct arm_instruction *instruction)
  2080. {
  2081. uint32_t imm = opcode & 0xff;
  2082. uint8_t Rd = (opcode >> 8) & 0x7;
  2083. uint8_t Rn;
  2084. uint32_t SP = opcode & (1 << 11);
  2085. char *reg_name;
  2086. instruction->type = ARM_ADD;
  2087. if (SP)
  2088. {
  2089. reg_name = "SP";
  2090. Rn = 13;
  2091. }
  2092. else
  2093. {
  2094. reg_name = "PC";
  2095. Rn = 15;
  2096. }
  2097. snprintf(instruction->text, 128,
  2098. "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32,
  2099. address, opcode, Rd, reg_name, imm * 4);
  2100. instruction->info.data_proc.variant = 0 /* immediate */;
  2101. instruction->info.data_proc.Rd = Rd;
  2102. instruction->info.data_proc.Rn = Rn;
  2103. instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
  2104. return ERROR_OK;
  2105. }
  2106. static int evaluate_adjust_stack_thumb(uint16_t opcode,
  2107. uint32_t address, struct arm_instruction *instruction)
  2108. {
  2109. uint32_t imm = opcode & 0x7f;
  2110. uint8_t opc = opcode & (1 << 7);
  2111. char *mnemonic;
  2112. if (opc)
  2113. {
  2114. instruction->type = ARM_SUB;
  2115. mnemonic = "SUB";
  2116. }
  2117. else
  2118. {
  2119. instruction->type = ARM_ADD;
  2120. mnemonic = "ADD";
  2121. }
  2122. snprintf(instruction->text, 128,
  2123. "0x%8.8" PRIx32 " 0x%4.4x \t%s\tSP, #%#" PRIx32,
  2124. address, opcode, mnemonic, imm*4);
  2125. instruction->info.data_proc.variant = 0 /* immediate */;
  2126. instruction->info.data_proc.Rd = 13 /*SP*/;
  2127. instruction->info.data_proc.Rn = 13 /*SP*/;
  2128. instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
  2129. return ERROR_OK;
  2130. }
  2131. static int evaluate_breakpoint_thumb(uint16_t opcode,
  2132. uint32_t address, struct arm_instruction *instruction)
  2133. {
  2134. uint32_t imm = opcode & 0xff;
  2135. instruction->type = ARM_BKPT;
  2136. snprintf(instruction->text, 128,
  2137. "0x%8.8" PRIx32 " 0x%4.4x \tBKPT\t%#2.2" PRIx32 "",
  2138. address, opcode, imm);
  2139. return ERROR_OK;
  2140. }
  2141. static int evaluate_load_store_multiple_thumb(uint16_t opcode,
  2142. uint32_t address, struct arm_instruction *instruction)
  2143. {
  2144. uint32_t reg_list = opcode & 0xff;
  2145. uint32_t L = opcode & (1 << 11);
  2146. uint32_t R = opcode & (1 << 8);
  2147. uint8_t Rn = (opcode >> 8) & 7;
  2148. uint8_t addr_mode = 0 /* IA */;
  2149. char reg_names[40];
  2150. char *reg_names_p;
  2151. char *mnemonic;
  2152. char ptr_name[7] = "";
  2153. int i;
  2154. /* REVISIT: in ThumbEE mode, there are no LDM or STM instructions.
  2155. * The STMIA and LDMIA opcodes are used for other instructions.
  2156. */
  2157. if ((opcode & 0xf000) == 0xc000)
  2158. { /* generic load/store multiple */
  2159. char *wback = "!";
  2160. if (L)
  2161. {
  2162. instruction->type = ARM_LDM;
  2163. mnemonic = "LDM";
  2164. if (opcode & (1 << Rn))
  2165. wback = "";
  2166. }
  2167. else
  2168. {
  2169. instruction->type = ARM_STM;
  2170. mnemonic = "STM";
  2171. }
  2172. snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback);
  2173. }
  2174. else
  2175. { /* push/pop */
  2176. Rn = 13; /* SP */
  2177. if (L)
  2178. {
  2179. instruction->type = ARM_LDM;
  2180. mnemonic = "POP";
  2181. if (R)
  2182. reg_list |= (1 << 15) /*PC*/;
  2183. }
  2184. else
  2185. {
  2186. instruction->type = ARM_STM;
  2187. mnemonic = "PUSH";
  2188. addr_mode = 3; /*DB*/
  2189. if (R)
  2190. reg_list |= (1 << 14) /*LR*/;
  2191. }
  2192. }
  2193. reg_names_p = reg_names;
  2194. for (i = 0; i <= 15; i++)
  2195. {
  2196. if (reg_list & (1 << i))
  2197. reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
  2198. }
  2199. if (reg_names_p > reg_names)
  2200. reg_names_p[-2] = '\0';
  2201. else /* invalid op : no registers */
  2202. reg_names[0] = '\0';
  2203. snprintf(instruction->text, 128,
  2204. "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%s{%s}",
  2205. address, opcode, mnemonic, ptr_name, reg_names);
  2206. instruction->info.load_store_multiple.register_list = reg_list;
  2207. instruction->info.load_store_multiple.Rn = Rn;
  2208. instruction->info.load_store_multiple.addressing_mode = addr_mode;
  2209. return ERROR_OK;
  2210. }
  2211. static int evaluate_cond_branch_thumb(uint16_t opcode,
  2212. uint32_t address, struct arm_instruction *instruction)
  2213. {
  2214. uint32_t offset = opcode & 0xff;
  2215. uint8_t cond = (opcode >> 8) & 0xf;
  2216. uint32_t target_address;
  2217. if (cond == 0xf)
  2218. {
  2219. instruction->type = ARM_SWI;
  2220. snprintf(instruction->text, 128,
  2221. "0x%8.8" PRIx32 " 0x%4.4x \tSVC\t%#2.2" PRIx32,
  2222. address, opcode, offset);
  2223. return ERROR_OK;
  2224. }
  2225. else if (cond == 0xe)
  2226. {
  2227. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  2228. snprintf(instruction->text, 128,
  2229. "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
  2230. address, opcode);
  2231. return ERROR_OK;
  2232. }
  2233. /* sign extend 8-bit offset */
  2234. if (offset & 0x00000080)
  2235. offset = 0xffffff00 | offset;
  2236. target_address = address + 4 + (offset << 1);
  2237. snprintf(instruction->text, 128,
  2238. "0x%8.8" PRIx32 " 0x%4.4x \tB%s\t%#8.8" PRIx32,
  2239. address, opcode,
  2240. arm_condition_strings[cond], target_address);
  2241. instruction->type = ARM_B;
  2242. instruction->info.b_bl_bx_blx.reg_operand = -1;
  2243. instruction->info.b_bl_bx_blx.target_address = target_address;
  2244. return ERROR_OK;
  2245. }
  2246. static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
  2247. struct arm_instruction *instruction)
  2248. {
  2249. unsigned offset;
  2250. /* added in Thumb2 */
  2251. offset = (opcode >> 3) & 0x1f;
  2252. offset |= (opcode & 0x0200) >> 4;
  2253. snprintf(instruction->text, 128,
  2254. "0x%8.8" PRIx32 " 0x%4.4x \tCB%sZ\tr%d, %#8.8" PRIx32,
  2255. address, opcode,
  2256. (opcode & 0x0800) ? "N" : "",
  2257. opcode & 0x7, address + 4 + (offset << 1));
  2258. return ERROR_OK;
  2259. }
  2260. static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
  2261. struct arm_instruction *instruction)
  2262. {
  2263. /* added in ARMv6 */
  2264. snprintf(instruction->text, 128,
  2265. "0x%8.8" PRIx32 " 0x%4.4x \t%cXT%c\tr%d, r%d",
  2266. address, opcode,
  2267. (opcode & 0x0080) ? 'U' : 'S',
  2268. (opcode & 0x0040) ? 'B' : 'H',
  2269. opcode & 0x7, (opcode >> 3) & 0x7);
  2270. return ERROR_OK;
  2271. }
  2272. static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
  2273. struct arm_instruction *instruction)
  2274. {
  2275. /* added in ARMv6 */
  2276. if ((opcode & 0x0ff0) == 0x0650)
  2277. snprintf(instruction->text, 128,
  2278. "0x%8.8" PRIx32 " 0x%4.4x \tSETEND %s",
  2279. address, opcode,
  2280. (opcode & 0x80) ? "BE" : "LE");
  2281. else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
  2282. snprintf(instruction->text, 128,
  2283. "0x%8.8" PRIx32 " 0x%4.4x \tCPSI%c\t%s%s%s",
  2284. address, opcode,
  2285. (opcode & 0x0010) ? 'D' : 'E',
  2286. (opcode & 0x0004) ? "A" : "",
  2287. (opcode & 0x0002) ? "I" : "",
  2288. (opcode & 0x0001) ? "F" : "");
  2289. return ERROR_OK;
  2290. }
  2291. static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
  2292. struct arm_instruction *instruction)
  2293. {
  2294. char *suffix;
  2295. /* added in ARMv6 */
  2296. switch ((opcode >> 6) & 3) {
  2297. case 0:
  2298. suffix = "";
  2299. break;
  2300. case 1:
  2301. suffix = "16";
  2302. break;
  2303. default:
  2304. suffix = "SH";
  2305. break;
  2306. }
  2307. snprintf(instruction->text, 128,
  2308. "0x%8.8" PRIx32 " 0x%4.4x \tREV%s\tr%d, r%d",
  2309. address, opcode, suffix,
  2310. opcode & 0x7, (opcode >> 3) & 0x7);
  2311. return ERROR_OK;
  2312. }
  2313. static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
  2314. struct arm_instruction *instruction)
  2315. {
  2316. char *hint;
  2317. switch ((opcode >> 4) & 0x0f) {
  2318. case 0:
  2319. hint = "NOP";
  2320. break;
  2321. case 1:
  2322. hint = "YIELD";
  2323. break;
  2324. case 2:
  2325. hint = "WFE";
  2326. break;
  2327. case 3:
  2328. hint = "WFI";
  2329. break;
  2330. case 4:
  2331. hint = "SEV";
  2332. break;
  2333. default:
  2334. hint = "HINT (UNRECOGNIZED)";
  2335. break;
  2336. }
  2337. snprintf(instruction->text, 128,
  2338. "0x%8.8" PRIx32 " 0x%4.4x \t%s",
  2339. address, opcode, hint);
  2340. return ERROR_OK;
  2341. }
  2342. static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
  2343. struct arm_instruction *instruction)
  2344. {
  2345. unsigned cond = (opcode >> 4) & 0x0f;
  2346. char *x = "", *y = "", *z = "";
  2347. if (opcode & 0x01)
  2348. z = (opcode & 0x02) ? "T" : "E";
  2349. if (opcode & 0x03)
  2350. y = (opcode & 0x04) ? "T" : "E";
  2351. if (opcode & 0x07)
  2352. x = (opcode & 0x08) ? "T" : "E";
  2353. snprintf(instruction->text, 128,
  2354. "0x%8.8" PRIx32 " 0x%4.4x \tIT%s%s%s\t%s",
  2355. address, opcode,
  2356. x, y, z, arm_condition_strings[cond]);
  2357. /* NOTE: strictly speaking, the next 1-4 instructions should
  2358. * now be displayed with the relevant conditional suffix...
  2359. */
  2360. return ERROR_OK;
  2361. }
  2362. int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
  2363. {
  2364. /* clear fields, to avoid confusion */
  2365. memset(instruction, 0, sizeof(struct arm_instruction));
  2366. instruction->opcode = opcode;
  2367. instruction->instruction_size = 2;
  2368. if ((opcode & 0xe000) == 0x0000)
  2369. {
  2370. /* add/substract register or immediate */
  2371. if ((opcode & 0x1800) == 0x1800)
  2372. return evaluate_add_sub_thumb(opcode, address, instruction);
  2373. /* shift by immediate */
  2374. else
  2375. return evaluate_shift_imm_thumb(opcode, address, instruction);
  2376. }
  2377. /* Add/substract/compare/move immediate */
  2378. if ((opcode & 0xe000) == 0x2000)
  2379. {
  2380. return evaluate_data_proc_imm_thumb(opcode, address, instruction);
  2381. }
  2382. /* Data processing instructions */
  2383. if ((opcode & 0xf800) == 0x4000)
  2384. {
  2385. return evaluate_data_proc_thumb(opcode, address, instruction);
  2386. }
  2387. /* Load from literal pool */
  2388. if ((opcode & 0xf800) == 0x4800)
  2389. {
  2390. return evaluate_load_literal_thumb(opcode, address, instruction);
  2391. }
  2392. /* Load/Store register offset */
  2393. if ((opcode & 0xf000) == 0x5000)
  2394. {
  2395. return evaluate_load_store_reg_thumb(opcode, address, instruction);
  2396. }
  2397. /* Load/Store immediate offset */
  2398. if (((opcode & 0xe000) == 0x6000)
  2399. ||((opcode & 0xf000) == 0x8000))
  2400. {
  2401. return evaluate_load_store_imm_thumb(opcode, address, instruction);
  2402. }
  2403. /* Load/Store from/to stack */
  2404. if ((opcode & 0xf000) == 0x9000)
  2405. {
  2406. return evaluate_load_store_stack_thumb(opcode, address, instruction);
  2407. }
  2408. /* Add to SP/PC */
  2409. if ((opcode & 0xf000) == 0xa000)
  2410. {
  2411. return evaluate_add_sp_pc_thumb(opcode, address, instruction);
  2412. }
  2413. /* Misc */
  2414. if ((opcode & 0xf000) == 0xb000)
  2415. {
  2416. switch ((opcode >> 8) & 0x0f) {
  2417. case 0x0:
  2418. return evaluate_adjust_stack_thumb(opcode, address, instruction);
  2419. case 0x1:
  2420. case 0x3:
  2421. case 0x9:
  2422. case 0xb:
  2423. return evaluate_cb_thumb(opcode, address, instruction);
  2424. case 0x2:
  2425. return evaluate_extend_thumb(opcode, address, instruction);
  2426. case 0x4:
  2427. case 0x5:
  2428. case 0xc:
  2429. case 0xd:
  2430. return evaluate_load_store_multiple_thumb(opcode, address,
  2431. instruction);
  2432. case 0x6:
  2433. return evaluate_cps_thumb(opcode, address, instruction);
  2434. case 0xa:
  2435. if ((opcode & 0x00c0) == 0x0080)
  2436. break;
  2437. return evaluate_byterev_thumb(opcode, address, instruction);
  2438. case 0xe:
  2439. return evaluate_breakpoint_thumb(opcode, address, instruction);
  2440. case 0xf:
  2441. if (opcode & 0x000f)
  2442. return evaluate_ifthen_thumb(opcode, address,
  2443. instruction);
  2444. else
  2445. return evaluate_hint_thumb(opcode, address,
  2446. instruction);
  2447. }
  2448. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  2449. snprintf(instruction->text, 128,
  2450. "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
  2451. address, opcode);
  2452. return ERROR_OK;
  2453. }
  2454. /* Load/Store multiple */
  2455. if ((opcode & 0xf000) == 0xc000)
  2456. {
  2457. return evaluate_load_store_multiple_thumb(opcode, address, instruction);
  2458. }
  2459. /* Conditional branch + SWI */
  2460. if ((opcode & 0xf000) == 0xd000)
  2461. {
  2462. return evaluate_cond_branch_thumb(opcode, address, instruction);
  2463. }
  2464. if ((opcode & 0xe000) == 0xe000)
  2465. {
  2466. /* Undefined instructions */
  2467. if ((opcode & 0xf801) == 0xe801)
  2468. {
  2469. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  2470. snprintf(instruction->text, 128,
  2471. "0x%8.8" PRIx32 " 0x%8.8x\t"
  2472. "UNDEFINED INSTRUCTION",
  2473. address, opcode);
  2474. return ERROR_OK;
  2475. }
  2476. else
  2477. { /* Branch to offset */
  2478. return evaluate_b_bl_blx_thumb(opcode, address, instruction);
  2479. }
  2480. }
  2481. LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
  2482. return -1;
  2483. }
  2484. static int t2ev_b_bl(uint32_t opcode, uint32_t address,
  2485. struct arm_instruction *instruction, char *cp)
  2486. {
  2487. unsigned offset;
  2488. unsigned b21 = 1 << 21;
  2489. unsigned b22 = 1 << 22;
  2490. /* instead of combining two smaller 16-bit branch instructions,
  2491. * Thumb2 uses only one larger 32-bit instruction.
  2492. */
  2493. offset = opcode & 0x7ff;
  2494. offset |= (opcode & 0x03ff0000) >> 5;
  2495. if (opcode & (1 << 26)) {
  2496. offset |= 0xff << 23;
  2497. if ((opcode & (1 << 11)) == 0)
  2498. b21 = 0;
  2499. if ((opcode & (1 << 13)) == 0)
  2500. b22 = 0;
  2501. } else {
  2502. if (opcode & (1 << 11))
  2503. b21 = 0;
  2504. if (opcode & (1 << 13))
  2505. b22 = 0;
  2506. }
  2507. offset |= b21;
  2508. offset |= b22;
  2509. address += 4;
  2510. address += offset << 1;
  2511. instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B;
  2512. instruction->info.b_bl_bx_blx.reg_operand = -1;
  2513. instruction->info.b_bl_bx_blx.target_address = address;
  2514. sprintf(cp, "%s\t%#8.8" PRIx32,
  2515. (opcode & (1 << 14)) ? "BL" : "B.W",
  2516. address);
  2517. return ERROR_OK;
  2518. }
  2519. static int t2ev_cond_b(uint32_t opcode, uint32_t address,
  2520. struct arm_instruction *instruction, char *cp)
  2521. {
  2522. unsigned offset;
  2523. unsigned b17 = 1 << 17;
  2524. unsigned b18 = 1 << 18;
  2525. unsigned cond = (opcode >> 22) & 0x0f;
  2526. offset = opcode & 0x7ff;
  2527. offset |= (opcode & 0x003f0000) >> 5;
  2528. if (opcode & (1 << 26)) {
  2529. offset |= 0xffff << 19;
  2530. if ((opcode & (1 << 11)) == 0)
  2531. b17 = 0;
  2532. if ((opcode & (1 << 13)) == 0)
  2533. b18 = 0;
  2534. } else {
  2535. if (opcode & (1 << 11))
  2536. b17 = 0;
  2537. if (opcode & (1 << 13))
  2538. b18 = 0;
  2539. }
  2540. offset |= b17;
  2541. offset |= b18;
  2542. address += 4;
  2543. address += offset << 1;
  2544. instruction->type = ARM_B;
  2545. instruction->info.b_bl_bx_blx.reg_operand = -1;
  2546. instruction->info.b_bl_bx_blx.target_address = address;
  2547. sprintf(cp, "B%s.W\t%#8.8" PRIx32,
  2548. arm_condition_strings[cond],
  2549. address);
  2550. return ERROR_OK;
  2551. }
  2552. static const char *special_name(int number)
  2553. {
  2554. char *special = "(RESERVED)";
  2555. switch (number) {
  2556. case 0:
  2557. special = "apsr";
  2558. break;
  2559. case 1:
  2560. special = "iapsr";
  2561. break;
  2562. case 2:
  2563. special = "eapsr";
  2564. break;
  2565. case 3:
  2566. special = "xpsr";
  2567. break;
  2568. case 5:
  2569. special = "ipsr";
  2570. break;
  2571. case 6:
  2572. special = "epsr";
  2573. break;
  2574. case 7:
  2575. special = "iepsr";
  2576. break;
  2577. case 8:
  2578. special = "msp";
  2579. break;
  2580. case 9:
  2581. special = "psp";
  2582. break;
  2583. case 16:
  2584. special = "primask";
  2585. break;
  2586. case 17:
  2587. special = "basepri";
  2588. break;
  2589. case 18:
  2590. special = "basepri_max";
  2591. break;
  2592. case 19:
  2593. special = "faultmask";
  2594. break;
  2595. case 20:
  2596. special = "control";
  2597. break;
  2598. }
  2599. return special;
  2600. }
  2601. static int t2ev_hint(uint32_t opcode, uint32_t address,
  2602. struct arm_instruction *instruction, char *cp)
  2603. {
  2604. const char *mnemonic;
  2605. if (opcode & 0x0700) {
  2606. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  2607. strcpy(cp, "UNDEFINED");
  2608. return ERROR_OK;
  2609. }
  2610. if (opcode & 0x00f0) {
  2611. sprintf(cp, "DBG\t#%d", (int) opcode & 0xf);
  2612. return ERROR_OK;
  2613. }
  2614. switch (opcode & 0x0f) {
  2615. case 0:
  2616. mnemonic = "NOP.W";
  2617. break;
  2618. case 1:
  2619. mnemonic = "YIELD.W";
  2620. break;
  2621. case 2:
  2622. mnemonic = "WFE.W";
  2623. break;
  2624. case 3:
  2625. mnemonic = "WFI.W";
  2626. break;
  2627. case 4:
  2628. mnemonic = "SEV.W";
  2629. break;
  2630. default:
  2631. mnemonic = "HINT.W (UNRECOGNIZED)";
  2632. break;
  2633. }
  2634. strcpy(cp, mnemonic);
  2635. return ERROR_OK;
  2636. }
  2637. static int t2ev_misc(uint32_t opcode, uint32_t address,
  2638. struct arm_instruction *instruction, char *cp)
  2639. {
  2640. const char *mnemonic;
  2641. switch ((opcode >> 4) & 0x0f) {
  2642. case 0:
  2643. mnemonic = "LEAVEX";
  2644. break;
  2645. case 1:
  2646. mnemonic = "ENTERX";
  2647. break;
  2648. case 2:
  2649. mnemonic = "CLREX";
  2650. break;
  2651. case 4:
  2652. mnemonic = "DSB";
  2653. break;
  2654. case 5:
  2655. mnemonic = "DMB";
  2656. break;
  2657. case 6:
  2658. mnemonic = "ISB";
  2659. break;
  2660. default:
  2661. return ERROR_INVALID_ARGUMENTS;
  2662. }
  2663. strcpy(cp, mnemonic);
  2664. return ERROR_OK;
  2665. }
  2666. static int t2ev_b_misc(uint32_t opcode, uint32_t address,
  2667. struct arm_instruction *instruction, char *cp)
  2668. {
  2669. /* permanently undefined */
  2670. if ((opcode & 0x07f07000) == 0x07f02000) {
  2671. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  2672. strcpy(cp, "UNDEFINED");
  2673. return ERROR_OK;
  2674. }
  2675. switch ((opcode >> 12) & 0x5) {
  2676. case 0x1:
  2677. case 0x5:
  2678. return t2ev_b_bl(opcode, address, instruction, cp);
  2679. case 0x4:
  2680. goto undef;
  2681. case 0:
  2682. if (((opcode >> 23) & 0x07) != 0x07)
  2683. return t2ev_cond_b(opcode, address, instruction, cp);
  2684. if (opcode & (1 << 26))
  2685. goto undef;
  2686. break;
  2687. }
  2688. switch ((opcode >> 20) & 0x7f) {
  2689. case 0x38:
  2690. case 0x39:
  2691. sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
  2692. (int) (opcode >> 16) & 0x0f);
  2693. return ERROR_OK;
  2694. case 0x3a:
  2695. return t2ev_hint(opcode, address, instruction, cp);
  2696. case 0x3b:
  2697. return t2ev_misc(opcode, address, instruction, cp);
  2698. case 0x3c:
  2699. sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f);
  2700. return ERROR_OK;
  2701. case 0x3e:
  2702. case 0x3f:
  2703. sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f,
  2704. special_name(opcode & 0xff));
  2705. return ERROR_OK;
  2706. }
  2707. undef:
  2708. return ERROR_INVALID_ARGUMENTS;
  2709. }
  2710. static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
  2711. struct arm_instruction *instruction, char *cp)
  2712. {
  2713. char *mnemonic = NULL;
  2714. int rn = (opcode >> 16) & 0xf;
  2715. int rd = (opcode >> 8) & 0xf;
  2716. unsigned immed = opcode & 0xff;
  2717. unsigned func;
  2718. bool one = false;
  2719. char *suffix = "";
  2720. char *suffix2 = "";
  2721. /* ARMv7-M: A5.3.2 Modified immediate constants */
  2722. func = (opcode >> 11) & 0x0e;
  2723. if (immed & 0x80)
  2724. func |= 1;
  2725. if (opcode & (1 << 26))
  2726. func |= 0x10;
  2727. /* "Modified" immediates */
  2728. switch (func >> 1) {
  2729. case 0:
  2730. break;
  2731. case 2:
  2732. immed <<= 8;
  2733. /* FALLTHROUGH */
  2734. case 1:
  2735. immed += immed << 16;
  2736. break;
  2737. case 3:
  2738. immed += immed << 8;
  2739. immed += immed << 16;
  2740. break;
  2741. default:
  2742. immed |= 0x80;
  2743. immed = ror(immed, func);
  2744. }
  2745. if (opcode & (1 << 20))
  2746. suffix = "S";
  2747. switch ((opcode >> 21) & 0xf) {
  2748. case 0:
  2749. if (rd == 0xf) {
  2750. instruction->type = ARM_TST;
  2751. mnemonic = "TST";
  2752. one = true;
  2753. suffix = "";
  2754. rd = rn;
  2755. } else {
  2756. instruction->type = ARM_AND;
  2757. mnemonic = "AND";
  2758. }
  2759. break;
  2760. case 1:
  2761. instruction->type = ARM_BIC;
  2762. mnemonic = "BIC";
  2763. break;
  2764. case 2:
  2765. if (rn == 0xf) {
  2766. instruction->type = ARM_MOV;
  2767. mnemonic = "MOV";
  2768. one = true;
  2769. suffix2 = ".W";
  2770. } else {
  2771. instruction->type = ARM_ORR;
  2772. mnemonic = "ORR";
  2773. }
  2774. break;
  2775. case 3:
  2776. if (rn == 0xf) {
  2777. instruction->type = ARM_MVN;
  2778. mnemonic = "MVN";
  2779. one = true;
  2780. } else {
  2781. // instruction->type = ARM_ORN;
  2782. mnemonic = "ORN";
  2783. }
  2784. break;
  2785. case 4:
  2786. if (rd == 0xf) {
  2787. instruction->type = ARM_TEQ;
  2788. mnemonic = "TEQ";
  2789. one = true;
  2790. suffix = "";
  2791. rd = rn;
  2792. } else {
  2793. instruction->type = ARM_EOR;
  2794. mnemonic = "EOR";
  2795. }
  2796. break;
  2797. case 8:
  2798. if (rd == 0xf) {
  2799. instruction->type = ARM_CMN;
  2800. mnemonic = "CMN";
  2801. one = true;
  2802. suffix = "";
  2803. rd = rn;
  2804. } else {
  2805. instruction->type = ARM_ADD;
  2806. mnemonic = "ADD";
  2807. suffix2 = ".W";
  2808. }
  2809. break;
  2810. case 10:
  2811. instruction->type = ARM_ADC;
  2812. mnemonic = "ADC";
  2813. suffix2 = ".W";
  2814. break;
  2815. case 11:
  2816. instruction->type = ARM_SBC;
  2817. mnemonic = "SBC";
  2818. break;
  2819. case 13:
  2820. if (rd == 0xf) {
  2821. instruction->type = ARM_CMP;
  2822. mnemonic = "CMP";
  2823. one = true;
  2824. suffix = "";
  2825. rd = rn;
  2826. } else {
  2827. instruction->type = ARM_SUB;
  2828. mnemonic = "SUB";
  2829. }
  2830. suffix2 = ".W";
  2831. break;
  2832. case 14:
  2833. instruction->type = ARM_RSB;
  2834. mnemonic = "RSB";
  2835. suffix2 = ".W";
  2836. break;
  2837. default:
  2838. return ERROR_INVALID_ARGUMENTS;
  2839. }
  2840. if (one)
  2841. sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x",
  2842. mnemonic, suffix2 ,rd, immed, immed);
  2843. else
  2844. sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x",
  2845. mnemonic, suffix, suffix2,
  2846. rd, rn, immed, immed);
  2847. return ERROR_OK;
  2848. }
  2849. static int t2ev_data_immed(uint32_t opcode, uint32_t address,
  2850. struct arm_instruction *instruction, char *cp)
  2851. {
  2852. char *mnemonic = NULL;
  2853. int rn = (opcode >> 16) & 0xf;
  2854. int rd = (opcode >> 8) & 0xf;
  2855. unsigned immed;
  2856. bool add = false;
  2857. bool is_signed = false;
  2858. immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 4);
  2859. if (opcode & (1 << 26))
  2860. immed |= (1 << 11);
  2861. switch ((opcode >> 20) & 0x1f) {
  2862. case 0:
  2863. if (rn == 0xf) {
  2864. add = true;
  2865. goto do_adr;
  2866. }
  2867. mnemonic = "ADDW";
  2868. break;
  2869. case 4:
  2870. immed |= (opcode >> 4) & 0xf000;
  2871. sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed);
  2872. return ERROR_OK;
  2873. case 0x0a:
  2874. if (rn == 0xf)
  2875. goto do_adr;
  2876. mnemonic = "SUBW";
  2877. break;
  2878. case 0x0c:
  2879. /* move constant to top 16 bits of register */
  2880. immed |= (opcode >> 4) & 0xf000;
  2881. sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rn, immed, immed);
  2882. return ERROR_OK;
  2883. case 0x10:
  2884. case 0x12:
  2885. is_signed = true;
  2886. case 0x18:
  2887. case 0x1a:
  2888. /* signed/unsigned saturated add */
  2889. immed = (opcode >> 6) & 0x03;
  2890. immed |= (opcode >> 10) & 0x1c;
  2891. sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
  2892. is_signed ? "S" : "U",
  2893. rd, (int) (opcode & 0x1f) + is_signed, rn,
  2894. (opcode & (1 << 21)) ? "ASR" : "LSL",
  2895. immed ? immed : 32);
  2896. return ERROR_OK;
  2897. case 0x14:
  2898. is_signed = true;
  2899. /* FALLTHROUGH */
  2900. case 0x1c:
  2901. /* signed/unsigned bitfield extract */
  2902. immed = (opcode >> 6) & 0x03;
  2903. immed |= (opcode >> 10) & 0x1c;
  2904. sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
  2905. is_signed ? "S" : "U",
  2906. rd, rn, immed,
  2907. (int) (opcode & 0x1f) + 1);
  2908. return ERROR_OK;
  2909. case 0x16:
  2910. immed = (opcode >> 6) & 0x03;
  2911. immed |= (opcode >> 10) & 0x1c;
  2912. if (rn == 0xf) /* bitfield clear */
  2913. sprintf(cp, "BFC\tr%d, #%d, #%d\t",
  2914. rd, immed,
  2915. (int) (opcode & 0x1f) + 1 - immed);
  2916. else /* bitfield insert */
  2917. sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
  2918. rd, rn, immed,
  2919. (int) (opcode & 0x1f) + 1 - immed);
  2920. return ERROR_OK;
  2921. default:
  2922. return ERROR_INVALID_ARGUMENTS;
  2923. }
  2924. sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
  2925. rd, rn, immed, immed);
  2926. return ERROR_OK;
  2927. do_adr:
  2928. address = thumb_alignpc4(address);
  2929. if (add)
  2930. address += immed;
  2931. else
  2932. address -= immed;
  2933. /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
  2934. * not hiding the pc-relative stuff will sometimes be useful.
  2935. */
  2936. sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
  2937. return ERROR_OK;
  2938. }
  2939. static int t2ev_store_single(uint32_t opcode, uint32_t address,
  2940. struct arm_instruction *instruction, char *cp)
  2941. {
  2942. unsigned op = (opcode >> 20) & 0xf;
  2943. char *size = "";
  2944. char *suffix = "";
  2945. char *p1 = "";
  2946. char *p2 = "]";
  2947. unsigned immed;
  2948. unsigned rn = (opcode >> 16) & 0x0f;
  2949. unsigned rt = (opcode >> 12) & 0x0f;
  2950. if (rn == 0xf)
  2951. return ERROR_INVALID_ARGUMENTS;
  2952. if (opcode & 0x0800)
  2953. op |= 1;
  2954. switch (op) {
  2955. /* byte */
  2956. case 0x8:
  2957. case 0x9:
  2958. size = "B";
  2959. goto imm12;
  2960. case 0x1:
  2961. size = "B";
  2962. goto imm8;
  2963. case 0x0:
  2964. size = "B";
  2965. break;
  2966. /* halfword */
  2967. case 0xa:
  2968. case 0xb:
  2969. size = "H";
  2970. goto imm12;
  2971. case 0x3:
  2972. size = "H";
  2973. goto imm8;
  2974. case 0x2:
  2975. size = "H";
  2976. break;
  2977. /* word */
  2978. case 0xc:
  2979. case 0xd:
  2980. goto imm12;
  2981. case 0x5:
  2982. goto imm8;
  2983. case 0x4:
  2984. break;
  2985. /* error */
  2986. default:
  2987. return ERROR_INVALID_ARGUMENTS;
  2988. }
  2989. sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
  2990. size, rt, rn, (int) opcode & 0x0f,
  2991. (int) (opcode >> 4) & 0x03);
  2992. return ERROR_OK;
  2993. imm12:
  2994. immed = opcode & 0x0fff;
  2995. sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x",
  2996. size, rt, rn, immed, immed);
  2997. return ERROR_OK;
  2998. imm8:
  2999. immed = opcode & 0x00ff;
  3000. switch (opcode & 0x700) {
  3001. case 0x600:
  3002. suffix = "T";
  3003. break;
  3004. case 0x000:
  3005. case 0x200:
  3006. return ERROR_INVALID_ARGUMENTS;
  3007. }
  3008. /* two indexed modes will write back rn */
  3009. if (opcode & 0x100) {
  3010. if (opcode & 0x400) /* pre-indexed */
  3011. p2 = "]!";
  3012. else { /* post-indexed */
  3013. p1 = "]";
  3014. p2 = "";
  3015. }
  3016. }
  3017. sprintf(cp, "STR%s%s\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
  3018. size, suffix, rt, rn, p1,
  3019. (opcode & 0x200) ? "" : "-",
  3020. immed, p2, immed);
  3021. return ERROR_OK;
  3022. }
  3023. static int t2ev_mul32(uint32_t opcode, uint32_t address,
  3024. struct arm_instruction *instruction, char *cp)
  3025. {
  3026. int ra = (opcode >> 12) & 0xf;
  3027. switch (opcode & 0x007000f0) {
  3028. case 0:
  3029. if (ra == 0xf)
  3030. sprintf(cp, "MUL\tr%d, r%d, r%d",
  3031. (int) (opcode >> 8) & 0xf,
  3032. (int) (opcode >> 16) & 0xf,
  3033. (int) (opcode >> 0) & 0xf);
  3034. else
  3035. sprintf(cp, "MLA\tr%d, r%d, r%d, r%d",
  3036. (int) (opcode >> 8) & 0xf,
  3037. (int) (opcode >> 16) & 0xf,
  3038. (int) (opcode >> 0) & 0xf, ra);
  3039. break;
  3040. case 0x10:
  3041. sprintf(cp, "MLS\tr%d, r%d, r%d, r%d",
  3042. (int) (opcode >> 8) & 0xf,
  3043. (int) (opcode >> 16) & 0xf,
  3044. (int) (opcode >> 0) & 0xf, ra);
  3045. break;
  3046. default:
  3047. return ERROR_INVALID_ARGUMENTS;
  3048. }
  3049. return ERROR_OK;
  3050. }
  3051. static int t2ev_mul64_div(uint32_t opcode, uint32_t address,
  3052. struct arm_instruction *instruction, char *cp)
  3053. {
  3054. int op = (opcode >> 4) & 0xf;
  3055. char *infix = "MUL";
  3056. op += (opcode >> 16) & 0x70;
  3057. switch (op) {
  3058. case 0x40:
  3059. case 0x60:
  3060. infix = "MLA";
  3061. /* FALLTHROUGH */
  3062. case 0:
  3063. case 0x20:
  3064. sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d",
  3065. (op & 0x20) ? 'U' : 'S',
  3066. infix,
  3067. (int) (opcode >> 12) & 0xf,
  3068. (int) (opcode >> 8) & 0xf,
  3069. (int) (opcode >> 16) & 0xf,
  3070. (int) (opcode >> 0) & 0xf);
  3071. break;
  3072. case 0x1f:
  3073. case 0x3f:
  3074. sprintf(cp, "%cDIV\tr%d, r%d, r%d",
  3075. (op & 0x20) ? 'U' : 'S',
  3076. (int) (opcode >> 8) & 0xf,
  3077. (int) (opcode >> 16) & 0xf,
  3078. (int) (opcode >> 0) & 0xf);
  3079. break;
  3080. default:
  3081. return ERROR_INVALID_ARGUMENTS;
  3082. }
  3083. return ERROR_OK;
  3084. }
  3085. static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
  3086. struct arm_instruction *instruction, char *cp)
  3087. {
  3088. int rn = (opcode >> 16) & 0xf;
  3089. int op = (opcode >> 22) & 0x6;
  3090. int t = (opcode >> 21) & 1;
  3091. unsigned registers = opcode & 0xffff;
  3092. char *mode = "";
  3093. if (opcode & (1 << 20))
  3094. op |= 1;
  3095. switch (op) {
  3096. case 0:
  3097. mode = "DB";
  3098. /* FALL THROUGH */
  3099. case 6:
  3100. sprintf(cp, "SRS%s\tsp%s, #%d", mode,
  3101. t ? "!" : "",
  3102. (unsigned) (opcode & 0x1f));
  3103. return ERROR_OK;
  3104. case 1:
  3105. mode = "DB";
  3106. /* FALL THROUGH */
  3107. case 7:
  3108. sprintf(cp, "RFE%s\tr%d%s", mode,
  3109. (unsigned) ((opcode >> 16) & 0xf),
  3110. t ? "!" : "");
  3111. return ERROR_OK;
  3112. case 2:
  3113. sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : "");
  3114. break;
  3115. case 3:
  3116. if (rn == 13 && t)
  3117. sprintf(cp, "POP.W\t");
  3118. else
  3119. sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : "");
  3120. break;
  3121. case 4:
  3122. if (rn == 13 && t)
  3123. sprintf(cp, "PUSH.W\t");
  3124. else
  3125. sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : "");
  3126. break;
  3127. case 5:
  3128. sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : "");
  3129. break;
  3130. default:
  3131. return ERROR_INVALID_ARGUMENTS;
  3132. }
  3133. cp = strchr(cp, 0);
  3134. *cp++ = '{';
  3135. for (t = 0; registers; t++, registers >>= 1) {
  3136. if ((registers & 1) == 0)
  3137. continue;
  3138. registers &= ~1;
  3139. sprintf(cp, "r%d%s", t, registers ? ", " : "");
  3140. cp = strchr(cp, 0);
  3141. }
  3142. *cp++ = '}';
  3143. *cp++ = 0;
  3144. return ERROR_OK;
  3145. }
  3146. /* load/store dual or exclusive, table branch */
  3147. static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
  3148. struct arm_instruction *instruction, char *cp)
  3149. {
  3150. unsigned op1op2 = (opcode >> 20) & 0x3;
  3151. unsigned op3 = (opcode >> 4) & 0xf;
  3152. char *mnemonic;
  3153. unsigned rn = (opcode >> 16) & 0xf;
  3154. unsigned rt = (opcode >> 12) & 0xf;
  3155. unsigned rd = (opcode >> 8) & 0xf;
  3156. unsigned imm = opcode & 0xff;
  3157. char *p1 = "";
  3158. char *p2 = "]";
  3159. op1op2 |= (opcode >> 21) & 0xc;
  3160. switch (op1op2) {
  3161. case 0:
  3162. mnemonic = "STREX";
  3163. goto strex;
  3164. case 1:
  3165. mnemonic = "LDREX";
  3166. goto ldrex;
  3167. case 2:
  3168. case 6:
  3169. case 8:
  3170. case 10:
  3171. case 12:
  3172. case 14:
  3173. mnemonic = "STRD";
  3174. goto immediate;
  3175. case 3:
  3176. case 7:
  3177. case 9:
  3178. case 11:
  3179. case 13:
  3180. case 15:
  3181. mnemonic = "LDRD";
  3182. if (rn == 15)
  3183. goto literal;
  3184. else
  3185. goto immediate;
  3186. case 4:
  3187. switch (op3) {
  3188. case 4:
  3189. mnemonic = "STREXB";
  3190. break;
  3191. case 5:
  3192. mnemonic = "STREXH";
  3193. break;
  3194. default:
  3195. return ERROR_INVALID_ARGUMENTS;
  3196. }
  3197. rd = opcode & 0xf;
  3198. imm = 0;
  3199. goto strex;
  3200. case 5:
  3201. switch (op3) {
  3202. case 0:
  3203. sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf);
  3204. return ERROR_OK;
  3205. case 1:
  3206. sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf);
  3207. return ERROR_OK;
  3208. case 4:
  3209. mnemonic = "LDREXB";
  3210. break;
  3211. case 5:
  3212. mnemonic = "LDREXH";
  3213. break;
  3214. default:
  3215. return ERROR_INVALID_ARGUMENTS;
  3216. }
  3217. imm = 0;
  3218. goto ldrex;
  3219. }
  3220. return ERROR_INVALID_ARGUMENTS;
  3221. strex:
  3222. imm <<= 2;
  3223. if (imm)
  3224. sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x",
  3225. mnemonic, rd, rt, rn, imm, imm);
  3226. else
  3227. sprintf(cp, "%s\tr%u, r%u, [r%u]",
  3228. mnemonic, rd, rt, rn);
  3229. return ERROR_OK;
  3230. ldrex:
  3231. imm <<= 2;
  3232. if (imm)
  3233. sprintf(cp, "%s\tr%u, [r%u, #%u]\t; %#2.2x",
  3234. mnemonic, rt, rn, imm, imm);
  3235. else
  3236. sprintf(cp, "%s\tr%u, [r%u]",
  3237. mnemonic, rt, rn);
  3238. return ERROR_OK;
  3239. immediate:
  3240. /* two indexed modes will write back rn */
  3241. if (opcode & (1 << 21)) {
  3242. if (opcode & (1 << 24)) /* pre-indexed */
  3243. p2 = "]!";
  3244. else { /* post-indexed */
  3245. p1 = "]";
  3246. p2 = "";
  3247. }
  3248. }
  3249. imm <<= 2;
  3250. sprintf(cp, "%s\tr%u, r%u, [r%u%s, #%s%u%s\t; %#2.2x",
  3251. mnemonic, rt, rd, rn, p1,
  3252. (opcode & (1 << 23)) ? "" : "-",
  3253. imm, p2, imm);
  3254. return ERROR_OK;
  3255. literal:
  3256. address = thumb_alignpc4(address);
  3257. imm <<= 2;
  3258. if (opcode & (1 << 23))
  3259. address += imm;
  3260. else
  3261. address -= imm;
  3262. sprintf(cp, "%s\tr%u, r%u, %#8.8" PRIx32,
  3263. mnemonic, rt, rd, address);
  3264. return ERROR_OK;
  3265. }
  3266. static int t2ev_data_shift(uint32_t opcode, uint32_t address,
  3267. struct arm_instruction *instruction, char *cp)
  3268. {
  3269. int op = (opcode >> 21) & 0xf;
  3270. int rd = (opcode >> 8) & 0xf;
  3271. int rn = (opcode >> 16) & 0xf;
  3272. int type = (opcode >> 4) & 0x3;
  3273. int immed = (opcode >> 6) & 0x3;
  3274. char *mnemonic;
  3275. char *suffix = "";
  3276. immed |= (opcode >> 10) & 0x1c;
  3277. if (opcode & (1 << 20))
  3278. suffix = "S";
  3279. switch (op) {
  3280. case 0:
  3281. if (rd == 0xf) {
  3282. if (!(opcode & (1 << 20)))
  3283. return ERROR_INVALID_ARGUMENTS;
  3284. instruction->type = ARM_TST;
  3285. mnemonic = "TST";
  3286. suffix = "";
  3287. goto two;
  3288. }
  3289. instruction->type = ARM_AND;
  3290. mnemonic = "AND";
  3291. break;
  3292. case 1:
  3293. instruction->type = ARM_BIC;
  3294. mnemonic = "BIC";
  3295. break;
  3296. case 2:
  3297. if (rn == 0xf) {
  3298. instruction->type = ARM_MOV;
  3299. switch (type) {
  3300. case 0:
  3301. if (immed == 0) {
  3302. sprintf(cp, "MOV%s.W\tr%d, r%d",
  3303. suffix, rd,
  3304. (int) (opcode & 0xf));
  3305. return ERROR_OK;
  3306. }
  3307. mnemonic = "LSL";
  3308. break;
  3309. case 1:
  3310. mnemonic = "LSR";
  3311. break;
  3312. case 2:
  3313. mnemonic = "ASR";
  3314. break;
  3315. default:
  3316. if (immed == 0) {
  3317. sprintf(cp, "RRX%s\tr%d, r%d",
  3318. suffix, rd,
  3319. (int) (opcode & 0xf));
  3320. return ERROR_OK;
  3321. }
  3322. mnemonic = "ROR";
  3323. break;
  3324. }
  3325. goto immediate;
  3326. } else {
  3327. instruction->type = ARM_ORR;
  3328. mnemonic = "ORR";
  3329. }
  3330. break;
  3331. case 3:
  3332. if (rn == 0xf) {
  3333. instruction->type = ARM_MVN;
  3334. mnemonic = "MVN";
  3335. rn = rd;
  3336. goto two;
  3337. } else {
  3338. // instruction->type = ARM_ORN;
  3339. mnemonic = "ORN";
  3340. }
  3341. break;
  3342. case 4:
  3343. if (rd == 0xf) {
  3344. if (!(opcode & (1 << 20)))
  3345. return ERROR_INVALID_ARGUMENTS;
  3346. instruction->type = ARM_TEQ;
  3347. mnemonic = "TEQ";
  3348. suffix = "";
  3349. goto two;
  3350. }
  3351. instruction->type = ARM_EOR;
  3352. mnemonic = "EOR";
  3353. break;
  3354. case 8:
  3355. if (rd == 0xf) {
  3356. if (!(opcode & (1 << 20)))
  3357. return ERROR_INVALID_ARGUMENTS;
  3358. instruction->type = ARM_CMN;
  3359. mnemonic = "CMN";
  3360. suffix = "";
  3361. goto two;
  3362. }
  3363. instruction->type = ARM_ADD;
  3364. mnemonic = "ADD";
  3365. break;
  3366. case 0xa:
  3367. instruction->type = ARM_ADC;
  3368. mnemonic = "ADC";
  3369. break;
  3370. case 0xb:
  3371. instruction->type = ARM_SBC;
  3372. mnemonic = "SBC";
  3373. break;
  3374. case 0xd:
  3375. if (rd == 0xf) {
  3376. if (!(opcode & (1 << 21)))
  3377. return ERROR_INVALID_ARGUMENTS;
  3378. instruction->type = ARM_CMP;
  3379. mnemonic = "CMP";
  3380. suffix = "";
  3381. goto two;
  3382. }
  3383. instruction->type = ARM_SUB;
  3384. mnemonic = "SUB";
  3385. break;
  3386. case 0xe:
  3387. instruction->type = ARM_RSB;
  3388. mnemonic = "RSB";
  3389. break;
  3390. default:
  3391. return ERROR_INVALID_ARGUMENTS;
  3392. }
  3393. sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
  3394. mnemonic, suffix, rd, rn, (int) (opcode & 0xf));
  3395. shift:
  3396. cp = strchr(cp, 0);
  3397. switch (type) {
  3398. case 0:
  3399. if (immed == 0)
  3400. return ERROR_OK;
  3401. suffix = "LSL";
  3402. break;
  3403. case 1:
  3404. suffix = "LSR";
  3405. if (immed == 32)
  3406. immed = 0;
  3407. break;
  3408. case 2:
  3409. suffix = "ASR";
  3410. if (immed == 32)
  3411. immed = 0;
  3412. break;
  3413. case 3:
  3414. if (immed == 0) {
  3415. strcpy(cp, ", RRX");
  3416. return ERROR_OK;
  3417. }
  3418. suffix = "ROR";
  3419. break;
  3420. }
  3421. sprintf(cp, ", %s #%d", suffix, immed ? immed : 32);
  3422. return ERROR_OK;
  3423. two:
  3424. sprintf(cp, "%s%s.W\tr%d, r%d",
  3425. mnemonic, suffix, rn, (int) (opcode & 0xf));
  3426. goto shift;
  3427. immediate:
  3428. sprintf(cp, "%s%s.W\tr%d, r%d, #%d",
  3429. mnemonic, suffix, rd,
  3430. (int) (opcode & 0xf), immed ? immed : 32);
  3431. return ERROR_OK;
  3432. }
  3433. static int t2ev_data_reg(uint32_t opcode, uint32_t address,
  3434. struct arm_instruction *instruction, char *cp)
  3435. {
  3436. char *mnemonic;
  3437. char * suffix = "";
  3438. if (((opcode >> 4) & 0xf) == 0) {
  3439. switch ((opcode >> 21) & 0x7) {
  3440. case 0:
  3441. mnemonic = "LSL";
  3442. break;
  3443. case 1:
  3444. mnemonic = "LSR";
  3445. break;
  3446. case 2:
  3447. mnemonic = "ASR";
  3448. break;
  3449. case 3:
  3450. mnemonic = "ROR";
  3451. break;
  3452. default:
  3453. return ERROR_INVALID_ARGUMENTS;
  3454. }
  3455. instruction->type = ARM_MOV;
  3456. if (opcode & (1 << 20))
  3457. suffix = "S";
  3458. sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
  3459. mnemonic, suffix,
  3460. (int) (opcode >> 8) & 0xf,
  3461. (int) (opcode >> 16) & 0xf,
  3462. (int) (opcode >> 0) & 0xf);
  3463. } else if (opcode & (1 << 7)) {
  3464. switch ((opcode >> 20) & 0xf) {
  3465. case 0:
  3466. case 1:
  3467. case 4:
  3468. case 5:
  3469. switch ((opcode >> 4) & 0x3) {
  3470. case 1:
  3471. suffix = ", ROR #8";
  3472. break;
  3473. case 2:
  3474. suffix = ", ROR #16";
  3475. break;
  3476. case 3:
  3477. suffix = ", ROR #24";
  3478. break;
  3479. }
  3480. sprintf(cp, "%cXT%c.W\tr%d, r%d%s",
  3481. (opcode & (1 << 24)) ? 'U' : 'S',
  3482. (opcode & (1 << 26)) ? 'B' : 'H',
  3483. (int) (opcode >> 8) & 0xf,
  3484. (int) (opcode >> 0) & 0xf,
  3485. suffix);
  3486. break;
  3487. case 8:
  3488. case 9:
  3489. case 0xa:
  3490. case 0xb:
  3491. if (opcode & (1 << 6))
  3492. return ERROR_INVALID_ARGUMENTS;
  3493. if (((opcode >> 12) & 0xf) != 0xf)
  3494. return ERROR_INVALID_ARGUMENTS;
  3495. if (!(opcode & (1 << 20)))
  3496. return ERROR_INVALID_ARGUMENTS;
  3497. switch (((opcode >> 19) & 0x04)
  3498. | ((opcode >> 4) & 0x3)) {
  3499. case 0:
  3500. mnemonic = "REV.W";
  3501. break;
  3502. case 1:
  3503. mnemonic = "REV16.W";
  3504. break;
  3505. case 2:
  3506. mnemonic = "RBIT";
  3507. break;
  3508. case 3:
  3509. mnemonic = "REVSH.W";
  3510. break;
  3511. case 4:
  3512. mnemonic = "CLZ";
  3513. break;
  3514. default:
  3515. return ERROR_INVALID_ARGUMENTS;
  3516. }
  3517. sprintf(cp, "%s\tr%d, r%d",
  3518. mnemonic,
  3519. (int) (opcode >> 8) & 0xf,
  3520. (int) (opcode >> 0) & 0xf);
  3521. break;
  3522. default:
  3523. return ERROR_INVALID_ARGUMENTS;
  3524. }
  3525. }
  3526. return ERROR_OK;
  3527. }
  3528. static int t2ev_load_word(uint32_t opcode, uint32_t address,
  3529. struct arm_instruction *instruction, char *cp)
  3530. {
  3531. int rn = (opcode >> 16) & 0xf;
  3532. int immed;
  3533. instruction->type = ARM_LDR;
  3534. if (rn == 0xf) {
  3535. immed = opcode & 0x0fff;
  3536. if ((opcode & (1 << 23)) == 0)
  3537. immed = -immed;
  3538. sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
  3539. (int) (opcode >> 12) & 0xf,
  3540. thumb_alignpc4(address) + immed);
  3541. return ERROR_OK;
  3542. }
  3543. if (opcode & (1 << 23)) {
  3544. immed = opcode & 0x0fff;
  3545. sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x",
  3546. (int) (opcode >> 12) & 0xf,
  3547. rn, immed, immed);
  3548. return ERROR_OK;
  3549. }
  3550. if (!(opcode & (0x3f << 6))) {
  3551. sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]",
  3552. (int) (opcode >> 12) & 0xf,
  3553. rn,
  3554. (int) (opcode >> 0) & 0xf,
  3555. (int) (opcode >> 4) & 0x3);
  3556. return ERROR_OK;
  3557. }
  3558. if (((opcode >> 8) & 0xf) == 0xe) {
  3559. immed = opcode & 0x00ff;
  3560. sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x",
  3561. (int) (opcode >> 12) & 0xf,
  3562. rn, immed, immed);
  3563. return ERROR_OK;
  3564. }
  3565. if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
  3566. char *p1 = "]", *p2 = "";
  3567. if (!(opcode & 0x0500))
  3568. return ERROR_INVALID_ARGUMENTS;
  3569. immed = opcode & 0x00ff;
  3570. /* two indexed modes will write back rn */
  3571. if (opcode & 0x100) {
  3572. if (opcode & 0x400) /* pre-indexed */
  3573. p2 = "]!";
  3574. else { /* post-indexed */
  3575. p1 = "]";
  3576. p2 = "";
  3577. }
  3578. }
  3579. sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
  3580. (int) (opcode >> 12) & 0xf,
  3581. rn, p1,
  3582. (opcode & 0x200) ? "" : "-",
  3583. immed, p2, immed);
  3584. return ERROR_OK;
  3585. }
  3586. return ERROR_INVALID_ARGUMENTS;
  3587. }
  3588. static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
  3589. struct arm_instruction *instruction, char *cp)
  3590. {
  3591. int rn = (opcode >> 16) & 0xf;
  3592. int rt = (opcode >> 12) & 0xf;
  3593. int op2 = (opcode >> 6) & 0x3f;
  3594. unsigned immed;
  3595. char *p1 = "", *p2 = "]";
  3596. char *mnemonic;
  3597. switch ((opcode >> 23) & 0x3) {
  3598. case 0:
  3599. if ((rn & rt) == 0xf) {
  3600. pld_literal:
  3601. immed = opcode & 0xfff;
  3602. address = thumb_alignpc4(address);
  3603. if (opcode & (1 << 23))
  3604. address += immed;
  3605. else
  3606. address -= immed;
  3607. sprintf(cp, "PLD\tr%d, %#8.8" PRIx32,
  3608. rt, address);
  3609. return ERROR_OK;
  3610. }
  3611. if (rn == 0x0f && rt != 0x0f) {
  3612. ldrb_literal:
  3613. immed = opcode & 0xfff;
  3614. address = thumb_alignpc4(address);
  3615. if (opcode & (1 << 23))
  3616. address += immed;
  3617. else
  3618. address -= immed;
  3619. sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32,
  3620. rt, address);
  3621. return ERROR_OK;
  3622. }
  3623. if (rn == 0x0f)
  3624. break;
  3625. if ((op2 & 0x3c) == 0x38) {
  3626. immed = opcode & 0xff;
  3627. sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x",
  3628. rt, rn, immed, immed);
  3629. return ERROR_OK;
  3630. }
  3631. if ((op2 & 0x3c) == 0x30) {
  3632. if (rt == 0x0f) {
  3633. immed = opcode & 0xff;
  3634. immed = -immed;
  3635. preload_immediate:
  3636. p1 = (opcode & (1 << 21)) ? "W" : "";
  3637. sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x",
  3638. p1, rn, immed, immed);
  3639. return ERROR_OK;
  3640. }
  3641. mnemonic = "LDRB";
  3642. ldrxb_immediate_t3:
  3643. immed = opcode & 0xff;
  3644. if (!(opcode & 0x200))
  3645. immed = -immed;
  3646. /* two indexed modes will write back rn */
  3647. if (opcode & 0x100) {
  3648. if (opcode & 0x400) /* pre-indexed */
  3649. p2 = "]!";
  3650. else { /* post-indexed */
  3651. p1 = "]";
  3652. p2 = "";
  3653. }
  3654. }
  3655. ldrxb_immediate_t2:
  3656. sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x",
  3657. mnemonic, rt, rn, p1,
  3658. immed, p2, immed);
  3659. return ERROR_OK;
  3660. }
  3661. if ((op2 & 0x24) == 0x24) {
  3662. mnemonic = "LDRB";
  3663. goto ldrxb_immediate_t3;
  3664. }
  3665. if (op2 == 0) {
  3666. int rm = opcode & 0xf;
  3667. if (rt == 0x0f)
  3668. sprintf(cp, "PLD\t");
  3669. else
  3670. sprintf(cp, "LDRB.W\tr%d, ", rt);
  3671. immed = (opcode >> 4) & 0x3;
  3672. cp = strchr(cp, 0);
  3673. sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
  3674. return ERROR_OK;
  3675. }
  3676. break;
  3677. case 1:
  3678. if ((rn & rt) == 0xf)
  3679. goto pld_literal;
  3680. if (rt == 0xf) {
  3681. immed = opcode & 0xfff;
  3682. goto preload_immediate;
  3683. }
  3684. if (rn == 0x0f)
  3685. goto ldrb_literal;
  3686. mnemonic = "LDRB.W";
  3687. immed = opcode & 0xfff;
  3688. goto ldrxb_immediate_t2;
  3689. case 2:
  3690. if ((rn & rt) == 0xf) {
  3691. immed = opcode & 0xfff;
  3692. address = thumb_alignpc4(address);
  3693. if (opcode & (1 << 23))
  3694. address += immed;
  3695. else
  3696. address -= immed;
  3697. sprintf(cp, "PLI\t%#8.8" PRIx32, address);
  3698. return ERROR_OK;
  3699. }
  3700. if (rn == 0xf && rt != 0xf) {
  3701. ldrsb_literal:
  3702. immed = opcode & 0xfff;
  3703. address = thumb_alignpc4(address);
  3704. if (opcode & (1 << 23))
  3705. address += immed;
  3706. else
  3707. address -= immed;
  3708. sprintf(cp, "LDRSB\t%#8.8" PRIx32, address);
  3709. return ERROR_OK;
  3710. }
  3711. if (rn == 0xf)
  3712. break;
  3713. if ((op2 & 0x3c) == 0x38) {
  3714. immed = opcode & 0xff;
  3715. sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x",
  3716. rt, rn, immed, immed);
  3717. return ERROR_OK;
  3718. }
  3719. if ((op2 & 0x3c) == 0x30) {
  3720. if (rt == 0xf) {
  3721. immed = opcode & 0xff;
  3722. immed = -immed; // pli
  3723. sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x",
  3724. rn, immed, -immed);
  3725. return ERROR_OK;
  3726. }
  3727. mnemonic = "LDRSB";
  3728. goto ldrxb_immediate_t3;
  3729. }
  3730. if ((op2 & 0x24) == 0x24) {
  3731. mnemonic = "LDRSB";
  3732. goto ldrxb_immediate_t3;
  3733. }
  3734. if (op2 == 0) {
  3735. int rm = opcode & 0xf;
  3736. if (rt == 0x0f)
  3737. sprintf(cp, "PLI\t");
  3738. else
  3739. sprintf(cp, "LDRSB.W\tr%d, ", rt);
  3740. immed = (opcode >> 4) & 0x3;
  3741. cp = strchr(cp, 0);
  3742. sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
  3743. return ERROR_OK;
  3744. }
  3745. break;
  3746. case 3:
  3747. if (rt == 0xf) {
  3748. immed = opcode & 0xfff;
  3749. sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x",
  3750. rn, immed, immed);
  3751. return ERROR_OK;
  3752. }
  3753. if (rn == 0xf)
  3754. goto ldrsb_literal;
  3755. immed = opcode & 0xfff;
  3756. mnemonic = "LDRSB";
  3757. goto ldrxb_immediate_t2;
  3758. }
  3759. return ERROR_INVALID_ARGUMENTS;
  3760. }
  3761. static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
  3762. struct arm_instruction *instruction, char *cp)
  3763. {
  3764. int rn = (opcode >> 16) & 0xf;
  3765. int rt = (opcode >> 12) & 0xf;
  3766. int op2 = (opcode >> 6) & 0x3f;
  3767. char *sign = "";
  3768. unsigned immed;
  3769. if (rt == 0xf) {
  3770. sprintf(cp, "HINT (UNALLOCATED)");
  3771. return ERROR_OK;
  3772. }
  3773. if (opcode & (1 << 24))
  3774. sign = "S";
  3775. if ((opcode & (1 << 23)) == 0) {
  3776. if (rn == 0xf) {
  3777. ldrh_literal:
  3778. immed = opcode & 0xfff;
  3779. address = thumb_alignpc4(address);
  3780. if (opcode & (1 << 23))
  3781. address += immed;
  3782. else
  3783. address -= immed;
  3784. sprintf(cp, "LDR%sH\tr%d, %#8.8" PRIx32,
  3785. sign, rt, address);
  3786. return ERROR_OK;
  3787. }
  3788. if (op2 == 0) {
  3789. int rm = opcode & 0xf;
  3790. immed = (opcode >> 4) & 0x3;
  3791. sprintf(cp, "LDR%sH.W\tr%d, [r%d, r%d, LSL #%d]",
  3792. sign, rt, rn, rm, immed);
  3793. return ERROR_OK;
  3794. }
  3795. if ((op2 & 0x3c) == 0x38) {
  3796. immed = opcode & 0xff;
  3797. sprintf(cp, "LDR%sHT\tr%d, [r%d, #%d]\t; %#2.2x",
  3798. sign, rt, rn, immed, immed);
  3799. return ERROR_OK;
  3800. }
  3801. if ((op2 & 0x3c) == 0x30 || (op2 & 0x24) == 0x24) {
  3802. char *p1 = "", *p2 = "]";
  3803. immed = opcode & 0xff;
  3804. if (!(opcode & 0x200))
  3805. immed = -immed;
  3806. /* two indexed modes will write back rn */
  3807. if (opcode & 0x100) {
  3808. if (opcode & 0x400) /* pre-indexed */
  3809. p2 = "]!";
  3810. else { /* post-indexed */
  3811. p1 = "]";
  3812. p2 = "";
  3813. }
  3814. }
  3815. sprintf(cp, "LDR%sH\tr%d, [r%d%s, #%d%s\t; %#8.8x",
  3816. sign, rt, rn, p1, immed, p2, immed);
  3817. return ERROR_OK;
  3818. }
  3819. } else {
  3820. if (rn == 0xf)
  3821. goto ldrh_literal;
  3822. immed = opcode & 0xfff;
  3823. sprintf(cp, "LDR%sH%s\tr%d, [r%d, #%d]\t; %#6.6x",
  3824. sign, *sign ? "" : ".W",
  3825. rt, rn, immed, immed);
  3826. return ERROR_OK;
  3827. }
  3828. return ERROR_INVALID_ARGUMENTS;
  3829. }
  3830. /*
  3831. * REVISIT for Thumb2 instructions, instruction->type and friends aren't
  3832. * always set. That means eventual arm_simulate_step() support for Thumb2
  3833. * will need work in this area.
  3834. */
  3835. int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction)
  3836. {
  3837. int retval;
  3838. uint16_t op;
  3839. uint32_t opcode;
  3840. char *cp;
  3841. /* clear low bit ... it's set on function pointers */
  3842. address &= ~1;
  3843. /* clear fields, to avoid confusion */
  3844. memset(instruction, 0, sizeof(struct arm_instruction));
  3845. /* read first halfword, see if this is the only one */
  3846. retval = target_read_u16(target, address, &op);
  3847. if (retval != ERROR_OK)
  3848. return retval;
  3849. switch (op & 0xf800) {
  3850. case 0xf800:
  3851. case 0xf000:
  3852. case 0xe800:
  3853. /* 32-bit instructions */
  3854. instruction->instruction_size = 4;
  3855. opcode = op << 16;
  3856. retval = target_read_u16(target, address + 2, &op);
  3857. if (retval != ERROR_OK)
  3858. return retval;
  3859. opcode |= op;
  3860. instruction->opcode = opcode;
  3861. break;
  3862. default:
  3863. /* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */
  3864. return thumb_evaluate_opcode(op, address, instruction);
  3865. }
  3866. snprintf(instruction->text, 128,
  3867. "0x%8.8" PRIx32 " 0x%8.8" PRIx32 "\t",
  3868. address, opcode);
  3869. cp = strchr(instruction->text, 0);
  3870. retval = ERROR_FAIL;
  3871. /* ARMv7-M: A5.3.1 Data processing (modified immediate) */
  3872. if ((opcode & 0x1a008000) == 0x10000000)
  3873. retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
  3874. /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
  3875. else if ((opcode & 0x1a008000) == 0x12000000)
  3876. retval = t2ev_data_immed(opcode, address, instruction, cp);
  3877. /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
  3878. else if ((opcode & 0x18008000) == 0x10008000)
  3879. retval = t2ev_b_misc(opcode, address, instruction, cp);
  3880. /* ARMv7-M: A5.3.5 Load/store multiple */
  3881. else if ((opcode & 0x1e400000) == 0x08000000)
  3882. retval = t2ev_ldm_stm(opcode, address, instruction, cp);
  3883. /* ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch */
  3884. else if ((opcode & 0x1e400000) == 0x08400000)
  3885. retval = t2ev_ldrex_strex(opcode, address, instruction, cp);
  3886. /* ARMv7-M: A5.3.7 Load word */
  3887. else if ((opcode & 0x1f700000) == 0x18500000)
  3888. retval = t2ev_load_word(opcode, address, instruction, cp);
  3889. /* ARMv7-M: A5.3.8 Load halfword, unallocated memory hints */
  3890. else if ((opcode & 0x1e700000) == 0x18300000)
  3891. retval = t2ev_load_halfword(opcode, address, instruction, cp);
  3892. /* ARMv7-M: A5.3.9 Load byte, memory hints */
  3893. else if ((opcode & 0x1e700000) == 0x18100000)
  3894. retval = t2ev_load_byte_hints(opcode, address, instruction, cp);
  3895. /* ARMv7-M: A5.3.10 Store single data item */
  3896. else if ((opcode & 0x1f100000) == 0x18000000)
  3897. retval = t2ev_store_single(opcode, address, instruction, cp);
  3898. /* ARMv7-M: A5.3.11 Data processing (shifted register) */
  3899. else if ((opcode & 0x1e000000) == 0x0a000000)
  3900. retval = t2ev_data_shift(opcode, address, instruction, cp);
  3901. /* ARMv7-M: A5.3.12 Data processing (register)
  3902. * and A5.3.13 Miscellaneous operations
  3903. */
  3904. else if ((opcode & 0x1f000000) == 0x1a000000)
  3905. retval = t2ev_data_reg(opcode, address, instruction, cp);
  3906. /* ARMv7-M: A5.3.14 Multiply, and multiply accumulate */
  3907. else if ((opcode & 0x1f800000) == 0x1b000000)
  3908. retval = t2ev_mul32(opcode, address, instruction, cp);
  3909. /* ARMv7-M: A5.3.15 Long multiply, long multiply accumulate, divide */
  3910. else if ((opcode & 0x1f800000) == 0x1b800000)
  3911. retval = t2ev_mul64_div(opcode, address, instruction, cp);
  3912. if (retval == ERROR_OK)
  3913. return retval;
  3914. /*
  3915. * Thumb2 also supports coprocessor, ThumbEE, and DSP/Media (SIMD)
  3916. * instructions; not yet handled here.
  3917. */
  3918. if (retval == ERROR_INVALID_ARGUMENTS) {
  3919. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  3920. strcpy(cp, "UNDEFINED OPCODE");
  3921. return ERROR_OK;
  3922. }
  3923. LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08" PRIx32 ")",
  3924. opcode);
  3925. strcpy(cp, "(32-bit Thumb2 ...)");
  3926. return ERROR_OK;
  3927. }
  3928. int arm_access_size(struct arm_instruction *instruction)
  3929. {
  3930. if ((instruction->type == ARM_LDRB)
  3931. || (instruction->type == ARM_LDRBT)
  3932. || (instruction->type == ARM_LDRSB)
  3933. || (instruction->type == ARM_STRB)
  3934. || (instruction->type == ARM_STRBT))
  3935. {
  3936. return 1;
  3937. }
  3938. else if ((instruction->type == ARM_LDRH)
  3939. || (instruction->type == ARM_LDRSH)
  3940. || (instruction->type == ARM_STRH))
  3941. {
  3942. return 2;
  3943. }
  3944. else if ((instruction->type == ARM_LDR)
  3945. || (instruction->type == ARM_LDRT)
  3946. || (instruction->type == ARM_STR)
  3947. || (instruction->type == ARM_STRT))
  3948. {
  3949. return 4;
  3950. }
  3951. else if ((instruction->type == ARM_LDRD)
  3952. || (instruction->type == ARM_STRD))
  3953. {
  3954. return 8;
  3955. }
  3956. else
  3957. {
  3958. LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
  3959. return 0;
  3960. }
  3961. }