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.
 
 
 
 
 
 

4428 lines
104 KiB

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