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.
 
 
 
 
 
 

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