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.
 
 
 
 
 
 

2115 lines
55 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2006 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "arm_disassembler.h"
  24. #include "log.h"
  25. /* textual represenation of the condition field */
  26. /* ALways (default) is ommitted (empty string) */
  27. char *arm_condition_strings[] =
  28. {
  29. "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
  30. };
  31. /* make up for C's missing ROR */
  32. uint32_t ror(uint32_t value, int places)
  33. {
  34. return (value >> places) | (value << (32 - places));
  35. }
  36. int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  37. {
  38. /* PLD */
  39. if ((opcode & 0x0d70f0000) == 0x0550f000)
  40. {
  41. instruction->type = ARM_PLD;
  42. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode);
  43. return ERROR_OK;
  44. }
  45. else
  46. {
  47. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  48. return ERROR_OK;
  49. }
  50. LOG_ERROR("should never reach this point");
  51. return -1;
  52. }
  53. int evaluate_swi(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  54. {
  55. instruction->type = ARM_SWI;
  56. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI 0x%6.6" PRIx32 "", address, opcode, (opcode & 0xffffff));
  57. return ERROR_OK;
  58. }
  59. int evaluate_blx_imm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  60. {
  61. int offset;
  62. uint32_t immediate;
  63. uint32_t target_address;
  64. instruction->type = ARM_BLX;
  65. immediate = opcode & 0x00ffffff;
  66. /* sign extend 24-bit immediate */
  67. if (immediate & 0x00800000)
  68. offset = 0xff000000 | immediate;
  69. else
  70. offset = immediate;
  71. /* shift two bits left */
  72. offset <<= 2;
  73. /* odd/event halfword */
  74. if (opcode & 0x01000000)
  75. offset |= 0x2;
  76. target_address = address + 8 + offset;
  77. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", address, opcode, target_address);
  78. instruction->info.b_bl_bx_blx.reg_operand = -1;
  79. instruction->info.b_bl_bx_blx.target_address = target_address;
  80. return ERROR_OK;
  81. }
  82. int evaluate_b_bl(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  83. {
  84. uint8_t L;
  85. uint32_t immediate;
  86. int offset;
  87. uint32_t target_address;
  88. immediate = opcode & 0x00ffffff;
  89. L = (opcode & 0x01000000) >> 24;
  90. /* sign extend 24-bit immediate */
  91. if (immediate & 0x00800000)
  92. offset = 0xff000000 | immediate;
  93. else
  94. offset = immediate;
  95. /* shift two bits left */
  96. offset <<= 2;
  97. target_address = address + 8 + offset;
  98. if (L)
  99. instruction->type = ARM_BL;
  100. else
  101. instruction->type = ARM_B;
  102. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32 , address, opcode,
  103. (L) ? "L" : "", COND(opcode), target_address);
  104. instruction->info.b_bl_bx_blx.reg_operand = -1;
  105. instruction->info.b_bl_bx_blx.target_address = target_address;
  106. return ERROR_OK;
  107. }
  108. /* Coprocessor load/store and double register transfers */
  109. /* both normal and extended instruction space (condition field b1111) */
  110. int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  111. {
  112. uint8_t cp_num = (opcode & 0xf00) >> 8;
  113. /* MCRR or MRRC */
  114. if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
  115. {
  116. uint8_t cp_opcode, Rd, Rn, CRm;
  117. char *mnemonic;
  118. cp_opcode = (opcode & 0xf0) >> 4;
  119. Rd = (opcode & 0xf000) >> 12;
  120. Rn = (opcode & 0xf0000) >> 16;
  121. CRm = (opcode & 0xf);
  122. /* MCRR */
  123. if ((opcode & 0x0ff00000) == 0x0c400000)
  124. {
  125. instruction->type = ARM_MCRR;
  126. mnemonic = "MCRR";
  127. }
  128. /* MRRC */
  129. if ((opcode & 0x0ff00000) == 0x0c500000)
  130. {
  131. instruction->type = ARM_MRRC;
  132. mnemonic = "MRRC";
  133. }
  134. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, %x, r%i, r%i, c%i",
  135. address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
  136. }
  137. else /* LDC or STC */
  138. {
  139. uint8_t CRd, Rn, offset;
  140. uint8_t U, N;
  141. char *mnemonic;
  142. char addressing_mode[32];
  143. CRd = (opcode & 0xf000) >> 12;
  144. Rn = (opcode & 0xf0000) >> 16;
  145. offset = (opcode & 0xff);
  146. /* load/store */
  147. if (opcode & 0x00100000)
  148. {
  149. instruction->type = ARM_LDC;
  150. mnemonic = "LDC";
  151. }
  152. else
  153. {
  154. instruction->type = ARM_STC;
  155. mnemonic = "STC";
  156. }
  157. U = (opcode & 0x00800000) >> 23;
  158. N = (opcode & 0x00400000) >> 22;
  159. /* addressing modes */
  160. if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */
  161. snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset);
  162. else if ((opcode & 0x01200000) == 0x01200000) /* immediate pre-indexed */
  163. snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]!", Rn, (U) ? "" : "-", offset);
  164. else if ((opcode & 0x01200000) == 0x00200000) /* immediate post-indexed */
  165. snprintf(addressing_mode, 32, "[r%i], #%s0x%2.2x*4", Rn, (U) ? "" : "-", offset);
  166. else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
  167. snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset);
  168. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s p%i, c%i, %s",
  169. address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) ? COND(opcode) : "2",
  170. (N) ? "L" : "",
  171. cp_num, CRd, addressing_mode);
  172. }
  173. return ERROR_OK;
  174. }
  175. /* Coprocessor data processing instructions */
  176. /* Coprocessor register transfer instructions */
  177. /* both normal and extended instruction space (condition field b1111) */
  178. int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  179. {
  180. char* cond;
  181. char* mnemonic;
  182. uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
  183. cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
  184. cp_num = (opcode & 0xf00) >> 8;
  185. CRd_Rd = (opcode & 0xf000) >> 12;
  186. CRn = (opcode & 0xf0000) >> 16;
  187. CRm = (opcode & 0xf);
  188. opcode_2 = (opcode & 0xe0) >> 5;
  189. /* CDP or MRC/MCR */
  190. if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */
  191. {
  192. if (opcode & 0x00100000) /* bit 20 set -> MRC */
  193. {
  194. instruction->type = ARM_MRC;
  195. mnemonic = "MRC";
  196. }
  197. else /* bit 20 not set -> MCR */
  198. {
  199. instruction->type = ARM_MCR;
  200. mnemonic = "MCR";
  201. }
  202. opcode_1 = (opcode & 0x00e00000) >> 21;
  203. 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",
  204. address, opcode, mnemonic, cond,
  205. cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
  206. }
  207. else /* bit 4 not set -> CDP */
  208. {
  209. instruction->type = ARM_CDP;
  210. mnemonic = "CDP";
  211. opcode_1 = (opcode & 0x00f00000) >> 20;
  212. 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",
  213. address, opcode, mnemonic, cond,
  214. cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
  215. }
  216. return ERROR_OK;
  217. }
  218. /* Load/store instructions */
  219. int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  220. {
  221. uint8_t I, P, U, B, W, L;
  222. uint8_t Rn, Rd;
  223. char *operation; /* "LDR" or "STR" */
  224. char *suffix; /* "", "B", "T", "BT" */
  225. char offset[32];
  226. /* examine flags */
  227. I = (opcode & 0x02000000) >> 25;
  228. P = (opcode & 0x01000000) >> 24;
  229. U = (opcode & 0x00800000) >> 23;
  230. B = (opcode & 0x00400000) >> 22;
  231. W = (opcode & 0x00200000) >> 21;
  232. L = (opcode & 0x00100000) >> 20;
  233. /* target register */
  234. Rd = (opcode & 0xf000) >> 12;
  235. /* base register */
  236. Rn = (opcode & 0xf0000) >> 16;
  237. instruction->info.load_store.Rd = Rd;
  238. instruction->info.load_store.Rn = Rn;
  239. instruction->info.load_store.U = U;
  240. /* determine operation */
  241. if (L)
  242. operation = "LDR";
  243. else
  244. operation = "STR";
  245. /* determine instruction type and suffix */
  246. if (B)
  247. {
  248. if ((P == 0) && (W == 1))
  249. {
  250. if (L)
  251. instruction->type = ARM_LDRBT;
  252. else
  253. instruction->type = ARM_STRBT;
  254. suffix = "BT";
  255. }
  256. else
  257. {
  258. if (L)
  259. instruction->type = ARM_LDRB;
  260. else
  261. instruction->type = ARM_STRB;
  262. suffix = "B";
  263. }
  264. }
  265. else
  266. {
  267. if ((P == 0) && (W == 1))
  268. {
  269. if (L)
  270. instruction->type = ARM_LDRT;
  271. else
  272. instruction->type = ARM_STRT;
  273. suffix = "T";
  274. }
  275. else
  276. {
  277. if (L)
  278. instruction->type = ARM_LDR;
  279. else
  280. instruction->type = ARM_STR;
  281. suffix = "";
  282. }
  283. }
  284. if (!I) /* #+-<offset_12> */
  285. {
  286. uint32_t offset_12 = (opcode & 0xfff);
  287. if (offset_12)
  288. snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
  289. else
  290. snprintf(offset, 32, "%s", "");
  291. instruction->info.load_store.offset_mode = 0;
  292. instruction->info.load_store.offset.offset = offset_12;
  293. }
  294. else /* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
  295. {
  296. uint8_t shift_imm, shift;
  297. uint8_t Rm;
  298. shift_imm = (opcode & 0xf80) >> 7;
  299. shift = (opcode & 0x60) >> 5;
  300. Rm = (opcode & 0xf);
  301. /* LSR encodes a shift by 32 bit as 0x0 */
  302. if ((shift == 0x1) && (shift_imm == 0x0))
  303. shift_imm = 0x20;
  304. /* ASR encodes a shift by 32 bit as 0x0 */
  305. if ((shift == 0x2) && (shift_imm == 0x0))
  306. shift_imm = 0x20;
  307. /* ROR by 32 bit is actually a RRX */
  308. if ((shift == 0x3) && (shift_imm == 0x0))
  309. shift = 0x4;
  310. instruction->info.load_store.offset_mode = 1;
  311. instruction->info.load_store.offset.reg.Rm = Rm;
  312. instruction->info.load_store.offset.reg.shift = shift;
  313. instruction->info.load_store.offset.reg.shift_imm = shift_imm;
  314. if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
  315. {
  316. snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
  317. }
  318. else /* +-<Rm>, <Shift>, #<shift_imm> */
  319. {
  320. switch (shift)
  321. {
  322. case 0x0: /* LSL */
  323. snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
  324. break;
  325. case 0x1: /* LSR */
  326. snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
  327. break;
  328. case 0x2: /* ASR */
  329. snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
  330. break;
  331. case 0x3: /* ROR */
  332. snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
  333. break;
  334. case 0x4: /* RRX */
  335. snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
  336. break;
  337. }
  338. }
  339. }
  340. if (P == 1)
  341. {
  342. if (W == 0) /* offset */
  343. {
  344. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
  345. address, opcode, operation, COND(opcode), suffix,
  346. Rd, Rn, offset);
  347. instruction->info.load_store.index_mode = 0;
  348. }
  349. else /* pre-indexed */
  350. {
  351. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
  352. address, opcode, operation, COND(opcode), suffix,
  353. Rd, Rn, offset);
  354. instruction->info.load_store.index_mode = 1;
  355. }
  356. }
  357. else /* post-indexed */
  358. {
  359. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
  360. address, opcode, operation, COND(opcode), suffix,
  361. Rd, Rn, offset);
  362. instruction->info.load_store.index_mode = 2;
  363. }
  364. return ERROR_OK;
  365. }
  366. /* Miscellaneous load/store instructions */
  367. int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  368. {
  369. uint8_t P, U, I, W, L, S, H;
  370. uint8_t Rn, Rd;
  371. char *operation; /* "LDR" or "STR" */
  372. char *suffix; /* "H", "SB", "SH", "D" */
  373. char offset[32];
  374. /* examine flags */
  375. P = (opcode & 0x01000000) >> 24;
  376. U = (opcode & 0x00800000) >> 23;
  377. I = (opcode & 0x00400000) >> 22;
  378. W = (opcode & 0x00200000) >> 21;
  379. L = (opcode & 0x00100000) >> 20;
  380. S = (opcode & 0x00000040) >> 6;
  381. H = (opcode & 0x00000020) >> 5;
  382. /* target register */
  383. Rd = (opcode & 0xf000) >> 12;
  384. /* base register */
  385. Rn = (opcode & 0xf0000) >> 16;
  386. instruction->info.load_store.Rd = Rd;
  387. instruction->info.load_store.Rn = Rn;
  388. instruction->info.load_store.U = U;
  389. /* determine instruction type and suffix */
  390. if (S) /* signed */
  391. {
  392. if (L) /* load */
  393. {
  394. if (H)
  395. {
  396. operation = "LDR";
  397. instruction->type = ARM_LDRSH;
  398. suffix = "SH";
  399. }
  400. else
  401. {
  402. operation = "LDR";
  403. instruction->type = ARM_LDRSB;
  404. suffix = "SB";
  405. }
  406. }
  407. else /* there are no signed stores, so this is used to encode double-register load/stores */
  408. {
  409. suffix = "D";
  410. if (H)
  411. {
  412. operation = "STR";
  413. instruction->type = ARM_STRD;
  414. }
  415. else
  416. {
  417. operation = "LDR";
  418. instruction->type = ARM_LDRD;
  419. }
  420. }
  421. }
  422. else /* unsigned */
  423. {
  424. suffix = "H";
  425. if (L) /* load */
  426. {
  427. operation = "LDR";
  428. instruction->type = ARM_LDRH;
  429. }
  430. else /* store */
  431. {
  432. operation = "STR";
  433. instruction->type = ARM_STRH;
  434. }
  435. }
  436. if (I) /* Immediate offset/index (#+-<offset_8>)*/
  437. {
  438. uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
  439. snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
  440. instruction->info.load_store.offset_mode = 0;
  441. instruction->info.load_store.offset.offset = offset_8;
  442. }
  443. else /* Register offset/index (+-<Rm>) */
  444. {
  445. uint8_t Rm;
  446. Rm = (opcode & 0xf);
  447. snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
  448. instruction->info.load_store.offset_mode = 1;
  449. instruction->info.load_store.offset.reg.Rm = Rm;
  450. instruction->info.load_store.offset.reg.shift = 0x0;
  451. instruction->info.load_store.offset.reg.shift_imm = 0x0;
  452. }
  453. if (P == 1)
  454. {
  455. if (W == 0) /* offset */
  456. {
  457. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
  458. address, opcode, operation, COND(opcode), suffix,
  459. Rd, Rn, offset);
  460. instruction->info.load_store.index_mode = 0;
  461. }
  462. else /* pre-indexed */
  463. {
  464. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
  465. address, opcode, operation, COND(opcode), suffix,
  466. Rd, Rn, offset);
  467. instruction->info.load_store.index_mode = 1;
  468. }
  469. }
  470. else /* post-indexed */
  471. {
  472. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
  473. address, opcode, operation, COND(opcode), suffix,
  474. Rd, Rn, offset);
  475. instruction->info.load_store.index_mode = 2;
  476. }
  477. return ERROR_OK;
  478. }
  479. /* Load/store multiples instructions */
  480. int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  481. {
  482. uint8_t P, U, S, W, L, Rn;
  483. uint32_t register_list;
  484. char *addressing_mode;
  485. char *mnemonic;
  486. char reg_list[69];
  487. char *reg_list_p;
  488. int i;
  489. int first_reg = 1;
  490. P = (opcode & 0x01000000) >> 24;
  491. U = (opcode & 0x00800000) >> 23;
  492. S = (opcode & 0x00400000) >> 22;
  493. W = (opcode & 0x00200000) >> 21;
  494. L = (opcode & 0x00100000) >> 20;
  495. register_list = (opcode & 0xffff);
  496. Rn = (opcode & 0xf0000) >> 16;
  497. instruction->info.load_store_multiple.Rn = Rn;
  498. instruction->info.load_store_multiple.register_list = register_list;
  499. instruction->info.load_store_multiple.S = S;
  500. instruction->info.load_store_multiple.W = W;
  501. if (L)
  502. {
  503. instruction->type = ARM_LDM;
  504. mnemonic = "LDM";
  505. }
  506. else
  507. {
  508. instruction->type = ARM_STM;
  509. mnemonic = "STM";
  510. }
  511. if (P)
  512. {
  513. if (U)
  514. {
  515. instruction->info.load_store_multiple.addressing_mode = 1;
  516. addressing_mode = "IB";
  517. }
  518. else
  519. {
  520. instruction->info.load_store_multiple.addressing_mode = 3;
  521. addressing_mode = "DB";
  522. }
  523. }
  524. else
  525. {
  526. if (U)
  527. {
  528. instruction->info.load_store_multiple.addressing_mode = 0;
  529. addressing_mode = "IA";
  530. }
  531. else
  532. {
  533. instruction->info.load_store_multiple.addressing_mode = 2;
  534. addressing_mode = "DA";
  535. }
  536. }
  537. reg_list_p = reg_list;
  538. for (i = 0; i <= 15; i++)
  539. {
  540. if ((register_list >> i) & 1)
  541. {
  542. if (first_reg)
  543. {
  544. first_reg = 0;
  545. reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), "r%i", i);
  546. }
  547. else
  548. {
  549. reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), ", r%i", i);
  550. }
  551. }
  552. }
  553. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i%s, {%s}%s",
  554. address, opcode, mnemonic, COND(opcode), addressing_mode,
  555. Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
  556. return ERROR_OK;
  557. }
  558. /* Multiplies, extra load/stores */
  559. int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  560. {
  561. /* Multiply (accumulate) (long) and Swap/swap byte */
  562. if ((opcode & 0x000000f0) == 0x00000090)
  563. {
  564. /* Multiply (accumulate) */
  565. if ((opcode & 0x0f800000) == 0x00000000)
  566. {
  567. uint8_t Rm, Rs, Rn, Rd, S;
  568. Rm = opcode & 0xf;
  569. Rs = (opcode & 0xf00) >> 8;
  570. Rn = (opcode & 0xf000) >> 12;
  571. Rd = (opcode & 0xf0000) >> 16;
  572. S = (opcode & 0x00100000) >> 20;
  573. /* examine A bit (accumulate) */
  574. if (opcode & 0x00200000)
  575. {
  576. instruction->type = ARM_MLA;
  577. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
  578. address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
  579. }
  580. else
  581. {
  582. instruction->type = ARM_MUL;
  583. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
  584. address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
  585. }
  586. return ERROR_OK;
  587. }
  588. /* Multiply (accumulate) long */
  589. if ((opcode & 0x0f800000) == 0x00800000)
  590. {
  591. char* mnemonic = NULL;
  592. uint8_t Rm, Rs, RdHi, RdLow, S;
  593. Rm = opcode & 0xf;
  594. Rs = (opcode & 0xf00) >> 8;
  595. RdHi = (opcode & 0xf000) >> 12;
  596. RdLow = (opcode & 0xf0000) >> 16;
  597. S = (opcode & 0x00100000) >> 20;
  598. switch ((opcode & 0x00600000) >> 21)
  599. {
  600. case 0x0:
  601. instruction->type = ARM_UMULL;
  602. mnemonic = "UMULL";
  603. break;
  604. case 0x1:
  605. instruction->type = ARM_UMLAL;
  606. mnemonic = "UMLAL";
  607. break;
  608. case 0x2:
  609. instruction->type = ARM_SMULL;
  610. mnemonic = "SMULL";
  611. break;
  612. case 0x3:
  613. instruction->type = ARM_SMLAL;
  614. mnemonic = "SMLAL";
  615. break;
  616. }
  617. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
  618. address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
  619. RdLow, RdHi, Rm, Rs);
  620. return ERROR_OK;
  621. }
  622. /* Swap/swap byte */
  623. if ((opcode & 0x0f800000) == 0x01000000)
  624. {
  625. uint8_t Rm, Rd, Rn;
  626. Rm = opcode & 0xf;
  627. Rd = (opcode & 0xf000) >> 12;
  628. Rn = (opcode & 0xf0000) >> 16;
  629. /* examine B flag */
  630. instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
  631. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
  632. address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
  633. return ERROR_OK;
  634. }
  635. }
  636. return evaluate_misc_load_store(opcode, address, instruction);
  637. }
  638. int evaluate_mrs_msr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  639. {
  640. int R = (opcode & 0x00400000) >> 22;
  641. char *PSR = (R) ? "SPSR" : "CPSR";
  642. /* Move register to status register (MSR) */
  643. if (opcode & 0x00200000)
  644. {
  645. instruction->type = ARM_MSR;
  646. /* immediate variant */
  647. if (opcode & 0x02000000)
  648. {
  649. uint8_t immediate = (opcode & 0xff);
  650. uint8_t rotate = (opcode & 0xf00);
  651. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 ,
  652. address, opcode, COND(opcode), PSR,
  653. (opcode & 0x10000) ? "c" : "",
  654. (opcode & 0x20000) ? "x" : "",
  655. (opcode & 0x40000) ? "s" : "",
  656. (opcode & 0x80000) ? "f" : "",
  657. ror(immediate, (rotate * 2))
  658. );
  659. }
  660. else /* register variant */
  661. {
  662. uint8_t Rm = opcode & 0xf;
  663. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
  664. address, opcode, COND(opcode), PSR,
  665. (opcode & 0x10000) ? "c" : "",
  666. (opcode & 0x20000) ? "x" : "",
  667. (opcode & 0x40000) ? "s" : "",
  668. (opcode & 0x80000) ? "f" : "",
  669. Rm
  670. );
  671. }
  672. }
  673. else /* Move status register to register (MRS) */
  674. {
  675. uint8_t Rd;
  676. instruction->type = ARM_MRS;
  677. Rd = (opcode & 0x0000f000) >> 12;
  678. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
  679. address, opcode, COND(opcode), Rd, PSR);
  680. }
  681. return ERROR_OK;
  682. }
  683. /* Miscellaneous instructions */
  684. int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  685. {
  686. /* MRS/MSR */
  687. if ((opcode & 0x000000f0) == 0x00000000)
  688. {
  689. evaluate_mrs_msr(opcode, address, instruction);
  690. }
  691. /* BX */
  692. if ((opcode & 0x006000f0) == 0x00200010)
  693. {
  694. uint8_t Rm;
  695. instruction->type = ARM_BX;
  696. Rm = opcode & 0xf;
  697. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
  698. address, opcode, COND(opcode), Rm);
  699. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  700. instruction->info.b_bl_bx_blx.target_address = -1;
  701. }
  702. /* CLZ */
  703. if ((opcode & 0x006000f0) == 0x00600010)
  704. {
  705. uint8_t Rm, Rd;
  706. instruction->type = ARM_CLZ;
  707. Rm = opcode & 0xf;
  708. Rd = (opcode & 0xf000) >> 12;
  709. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
  710. address, opcode, COND(opcode), Rd, Rm);
  711. }
  712. /* BLX(2) */
  713. if ((opcode & 0x006000f0) == 0x00200030)
  714. {
  715. uint8_t Rm;
  716. instruction->type = ARM_BLX;
  717. Rm = opcode & 0xf;
  718. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
  719. address, opcode, COND(opcode), Rm);
  720. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  721. instruction->info.b_bl_bx_blx.target_address = -1;
  722. }
  723. /* Enhanced DSP add/subtracts */
  724. if ((opcode & 0x0000000f0) == 0x00000050)
  725. {
  726. uint8_t Rm, Rd, Rn;
  727. char *mnemonic = NULL;
  728. Rm = opcode & 0xf;
  729. Rd = (opcode & 0xf000) >> 12;
  730. Rn = (opcode & 0xf0000) >> 16;
  731. switch ((opcode & 0x00600000) >> 21)
  732. {
  733. case 0x0:
  734. instruction->type = ARM_QADD;
  735. mnemonic = "QADD";
  736. break;
  737. case 0x1:
  738. instruction->type = ARM_QSUB;
  739. mnemonic = "QSUB";
  740. break;
  741. case 0x2:
  742. instruction->type = ARM_QDADD;
  743. mnemonic = "QDADD";
  744. break;
  745. case 0x3:
  746. instruction->type = ARM_QDSUB;
  747. mnemonic = "QDSUB";
  748. break;
  749. }
  750. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
  751. address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
  752. }
  753. /* Software breakpoints */
  754. if ((opcode & 0x0000000f0) == 0x00000070)
  755. {
  756. uint32_t immediate;
  757. instruction->type = ARM_BKPT;
  758. immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
  759. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
  760. address, opcode, immediate);
  761. }
  762. /* Enhanced DSP multiplies */
  763. if ((opcode & 0x000000090) == 0x00000080)
  764. {
  765. int x = (opcode & 0x20) >> 5;
  766. int y = (opcode & 0x40) >> 6;
  767. /* SMLA < x><y> */
  768. if ((opcode & 0x00600000) == 0x00000000)
  769. {
  770. uint8_t Rd, Rm, Rs, Rn;
  771. instruction->type = ARM_SMLAxy;
  772. Rd = (opcode & 0xf0000) >> 16;
  773. Rm = (opcode & 0xf);
  774. Rs = (opcode & 0xf00) >> 8;
  775. Rn = (opcode & 0xf000) >> 12;
  776. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
  777. address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
  778. Rd, Rm, Rs, Rn);
  779. }
  780. /* SMLAL < x><y> */
  781. if ((opcode & 0x00600000) == 0x00400000)
  782. {
  783. uint8_t RdLow, RdHi, Rm, Rs;
  784. instruction->type = ARM_SMLAxy;
  785. RdHi = (opcode & 0xf0000) >> 16;
  786. RdLow = (opcode & 0xf000) >> 12;
  787. Rm = (opcode & 0xf);
  788. Rs = (opcode & 0xf00) >> 8;
  789. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
  790. address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
  791. RdLow, RdHi, Rm, Rs);
  792. }
  793. /* SMLAW < y> */
  794. if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
  795. {
  796. uint8_t Rd, Rm, Rs, Rn;
  797. instruction->type = ARM_SMLAWy;
  798. Rd = (opcode & 0xf0000) >> 16;
  799. Rm = (opcode & 0xf);
  800. Rs = (opcode & 0xf00) >> 8;
  801. Rn = (opcode & 0xf000) >> 12;
  802. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
  803. address, opcode, (y) ? "T" : "B", COND(opcode),
  804. Rd, Rm, Rs, Rn);
  805. }
  806. /* SMUL < x><y> */
  807. if ((opcode & 0x00600000) == 0x00300000)
  808. {
  809. uint8_t Rd, Rm, Rs;
  810. instruction->type = ARM_SMULxy;
  811. Rd = (opcode & 0xf0000) >> 16;
  812. Rm = (opcode & 0xf);
  813. Rs = (opcode & 0xf00) >> 8;
  814. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
  815. address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
  816. Rd, Rm, Rs);
  817. }
  818. /* SMULW < y> */
  819. if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
  820. {
  821. uint8_t Rd, Rm, Rs;
  822. instruction->type = ARM_SMULWy;
  823. Rd = (opcode & 0xf0000) >> 16;
  824. Rm = (opcode & 0xf);
  825. Rs = (opcode & 0xf00) >> 8;
  826. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
  827. address, opcode, (y) ? "T" : "B", COND(opcode),
  828. Rd, Rm, Rs);
  829. }
  830. }
  831. return ERROR_OK;
  832. }
  833. int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  834. {
  835. uint8_t I, op, S, Rn, Rd;
  836. char *mnemonic = NULL;
  837. char shifter_operand[32];
  838. I = (opcode & 0x02000000) >> 25;
  839. op = (opcode & 0x01e00000) >> 21;
  840. S = (opcode & 0x00100000) >> 20;
  841. Rd = (opcode & 0xf000) >> 12;
  842. Rn = (opcode & 0xf0000) >> 16;
  843. instruction->info.data_proc.Rd = Rd;
  844. instruction->info.data_proc.Rn = Rn;
  845. instruction->info.data_proc.S = S;
  846. switch (op)
  847. {
  848. case 0x0:
  849. instruction->type = ARM_AND;
  850. mnemonic = "AND";
  851. break;
  852. case 0x1:
  853. instruction->type = ARM_EOR;
  854. mnemonic = "EOR";
  855. break;
  856. case 0x2:
  857. instruction->type = ARM_SUB;
  858. mnemonic = "SUB";
  859. break;
  860. case 0x3:
  861. instruction->type = ARM_RSB;
  862. mnemonic = "RSB";
  863. break;
  864. case 0x4:
  865. instruction->type = ARM_ADD;
  866. mnemonic = "ADD";
  867. break;
  868. case 0x5:
  869. instruction->type = ARM_ADC;
  870. mnemonic = "ADC";
  871. break;
  872. case 0x6:
  873. instruction->type = ARM_SBC;
  874. mnemonic = "SBC";
  875. break;
  876. case 0x7:
  877. instruction->type = ARM_RSC;
  878. mnemonic = "RSC";
  879. break;
  880. case 0x8:
  881. instruction->type = ARM_TST;
  882. mnemonic = "TST";
  883. break;
  884. case 0x9:
  885. instruction->type = ARM_TEQ;
  886. mnemonic = "TEQ";
  887. break;
  888. case 0xa:
  889. instruction->type = ARM_CMP;
  890. mnemonic = "CMP";
  891. break;
  892. case 0xb:
  893. instruction->type = ARM_CMN;
  894. mnemonic = "CMN";
  895. break;
  896. case 0xc:
  897. instruction->type = ARM_ORR;
  898. mnemonic = "ORR";
  899. break;
  900. case 0xd:
  901. instruction->type = ARM_MOV;
  902. mnemonic = "MOV";
  903. break;
  904. case 0xe:
  905. instruction->type = ARM_BIC;
  906. mnemonic = "BIC";
  907. break;
  908. case 0xf:
  909. instruction->type = ARM_MVN;
  910. mnemonic = "MVN";
  911. break;
  912. }
  913. if (I) /* immediate shifter operand (#<immediate>)*/
  914. {
  915. uint8_t immed_8 = opcode & 0xff;
  916. uint8_t rotate_imm = (opcode & 0xf00) >> 8;
  917. uint32_t immediate;
  918. immediate = ror(immed_8, rotate_imm * 2);
  919. snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
  920. instruction->info.data_proc.variant = 0;
  921. instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
  922. }
  923. else /* register-based shifter operand */
  924. {
  925. uint8_t shift, Rm;
  926. shift = (opcode & 0x60) >> 5;
  927. Rm = (opcode & 0xf);
  928. if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
  929. {
  930. uint8_t shift_imm;
  931. shift_imm = (opcode & 0xf80) >> 7;
  932. instruction->info.data_proc.variant = 1;
  933. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
  934. instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
  935. instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
  936. /* LSR encodes a shift by 32 bit as 0x0 */
  937. if ((shift == 0x1) && (shift_imm == 0x0))
  938. shift_imm = 0x20;
  939. /* ASR encodes a shift by 32 bit as 0x0 */
  940. if ((shift == 0x2) && (shift_imm == 0x0))
  941. shift_imm = 0x20;
  942. /* ROR by 32 bit is actually a RRX */
  943. if ((shift == 0x3) && (shift_imm == 0x0))
  944. shift = 0x4;
  945. if ((shift_imm == 0x0) && (shift == 0x0))
  946. {
  947. snprintf(shifter_operand, 32, "r%i", Rm);
  948. }
  949. else
  950. {
  951. if (shift == 0x0) /* LSL */
  952. {
  953. snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm);
  954. }
  955. else if (shift == 0x1) /* LSR */
  956. {
  957. snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
  958. }
  959. else if (shift == 0x2) /* ASR */
  960. {
  961. snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
  962. }
  963. else if (shift == 0x3) /* ROR */
  964. {
  965. snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
  966. }
  967. else if (shift == 0x4) /* RRX */
  968. {
  969. snprintf(shifter_operand, 32, "r%i, RRX", Rm);
  970. }
  971. }
  972. }
  973. else /* Register shifts ("<Rm>, <shift> <Rs>") */
  974. {
  975. uint8_t Rs = (opcode & 0xf00) >> 8;
  976. instruction->info.data_proc.variant = 2;
  977. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
  978. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
  979. instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
  980. if (shift == 0x0) /* LSL */
  981. {
  982. snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
  983. }
  984. else if (shift == 0x1) /* LSR */
  985. {
  986. snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
  987. }
  988. else if (shift == 0x2) /* ASR */
  989. {
  990. snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
  991. }
  992. else if (shift == 0x3) /* ROR */
  993. {
  994. snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
  995. }
  996. }
  997. }
  998. if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
  999. {
  1000. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
  1001. address, opcode, mnemonic, COND(opcode),
  1002. (S) ? "S" : "", Rd, Rn, shifter_operand);
  1003. }
  1004. else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
  1005. {
  1006. if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */
  1007. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",address, opcode);
  1008. else
  1009. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
  1010. address, opcode, mnemonic, COND(opcode),
  1011. (S) ? "S" : "", Rd, shifter_operand);
  1012. }
  1013. else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
  1014. {
  1015. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
  1016. address, opcode, mnemonic, COND(opcode),
  1017. Rn, shifter_operand);
  1018. }
  1019. return ERROR_OK;
  1020. }
  1021. int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
  1022. {
  1023. /* clear fields, to avoid confusion */
  1024. memset(instruction, 0, sizeof(arm_instruction_t));
  1025. instruction->opcode = opcode;
  1026. /* catch opcodes with condition field [31:28] = b1111 */
  1027. if ((opcode & 0xf0000000) == 0xf0000000)
  1028. {
  1029. /* Undefined instruction (or ARMv5E cache preload PLD) */
  1030. if ((opcode & 0x08000000) == 0x00000000)
  1031. return evaluate_pld(opcode, address, instruction);
  1032. /* Undefined instruction */
  1033. if ((opcode & 0x0e000000) == 0x08000000)
  1034. {
  1035. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1036. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
  1037. return ERROR_OK;
  1038. }
  1039. /* Branch and branch with link and change to Thumb */
  1040. if ((opcode & 0x0e000000) == 0x0a000000)
  1041. return evaluate_blx_imm(opcode, address, instruction);
  1042. /* Extended coprocessor opcode space (ARMv5 and higher)*/
  1043. /* Coprocessor load/store and double register transfers */
  1044. if ((opcode & 0x0e000000) == 0x0c000000)
  1045. return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
  1046. /* Coprocessor data processing */
  1047. if ((opcode & 0x0f000100) == 0x0c000000)
  1048. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1049. /* Coprocessor register transfers */
  1050. if ((opcode & 0x0f000010) == 0x0c000010)
  1051. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1052. /* Undefined instruction */
  1053. if ((opcode & 0x0f000000) == 0x0f000000)
  1054. {
  1055. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1056. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
  1057. return ERROR_OK;
  1058. }
  1059. }
  1060. /* catch opcodes with [27:25] = b000 */
  1061. if ((opcode & 0x0e000000) == 0x00000000)
  1062. {
  1063. /* Multiplies, extra load/stores */
  1064. if ((opcode & 0x00000090) == 0x00000090)
  1065. return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
  1066. /* Miscellaneous instructions */
  1067. if ((opcode & 0x0f900000) == 0x01000000)
  1068. return evaluate_misc_instr(opcode, address, instruction);
  1069. return evaluate_data_proc(opcode, address, instruction);
  1070. }
  1071. /* catch opcodes with [27:25] = b001 */
  1072. if ((opcode & 0x0e000000) == 0x02000000)
  1073. {
  1074. /* Undefined instruction */
  1075. if ((opcode & 0x0fb00000) == 0x03000000)
  1076. {
  1077. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1078. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
  1079. return ERROR_OK;
  1080. }
  1081. /* Move immediate to status register */
  1082. if ((opcode & 0x0fb00000) == 0x03200000)
  1083. return evaluate_mrs_msr(opcode, address, instruction);
  1084. return evaluate_data_proc(opcode, address, instruction);
  1085. }
  1086. /* catch opcodes with [27:25] = b010 */
  1087. if ((opcode & 0x0e000000) == 0x04000000)
  1088. {
  1089. /* Load/store immediate offset */
  1090. return evaluate_load_store(opcode, address, instruction);
  1091. }
  1092. /* catch opcodes with [27:25] = b011 */
  1093. if ((opcode & 0x0e000000) == 0x06000000)
  1094. {
  1095. /* Undefined instruction */
  1096. if ((opcode & 0x00000010) == 0x00000010)
  1097. {
  1098. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1099. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
  1100. return ERROR_OK;
  1101. }
  1102. /* Load/store register offset */
  1103. return evaluate_load_store(opcode, address, instruction);
  1104. }
  1105. /* catch opcodes with [27:25] = b100 */
  1106. if ((opcode & 0x0e000000) == 0x08000000)
  1107. {
  1108. /* Load/store multiple */
  1109. return evaluate_ldm_stm(opcode, address, instruction);
  1110. }
  1111. /* catch opcodes with [27:25] = b101 */
  1112. if ((opcode & 0x0e000000) == 0x0a000000)
  1113. {
  1114. /* Branch and branch with link */
  1115. return evaluate_b_bl(opcode, address, instruction);
  1116. }
  1117. /* catch opcodes with [27:25] = b110 */
  1118. if ((opcode & 0x0e000000) == 0x0a000000)
  1119. {
  1120. /* Coprocessor load/store and double register transfers */
  1121. return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
  1122. }
  1123. /* catch opcodes with [27:25] = b111 */
  1124. if ((opcode & 0x0e000000) == 0x0e000000)
  1125. {
  1126. /* Software interrupt */
  1127. if ((opcode & 0x0f000000) == 0x0f000000)
  1128. return evaluate_swi(opcode, address, instruction);
  1129. /* Coprocessor data processing */
  1130. if ((opcode & 0x0f000010) == 0x0e000000)
  1131. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1132. /* Coprocessor register transfers */
  1133. if ((opcode & 0x0f000010) == 0x0e000010)
  1134. return evaluate_cdp_mcr_mrc(opcode, address, instruction);
  1135. }
  1136. LOG_ERROR("should never reach this point");
  1137. return -1;
  1138. }
  1139. int evaluate_b_bl_blx_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1140. {
  1141. uint32_t offset = opcode & 0x7ff;
  1142. uint32_t opc = (opcode >> 11) & 0x3;
  1143. uint32_t target_address;
  1144. char *mnemonic = NULL;
  1145. /* sign extend 11-bit offset */
  1146. if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
  1147. offset = 0xfffff800 | offset;
  1148. target_address = address + 4 + (offset << 1);
  1149. switch (opc)
  1150. {
  1151. /* unconditional branch */
  1152. case 0:
  1153. instruction->type = ARM_B;
  1154. mnemonic = "B";
  1155. break;
  1156. /* BLX suffix */
  1157. case 1:
  1158. instruction->type = ARM_BLX;
  1159. mnemonic = "BLX";
  1160. break;
  1161. /* BL/BLX prefix */
  1162. case 2:
  1163. instruction->type = ARM_UNKNOWN_INSTUCTION;
  1164. mnemonic = "prefix";
  1165. target_address = offset << 12;
  1166. break;
  1167. /* BL suffix */
  1168. case 3:
  1169. instruction->type = ARM_BL;
  1170. mnemonic = "BL";
  1171. break;
  1172. }
  1173. /* TODO: deals correctly with dual opcodes BL/BLX ... */
  1174. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s 0x%8.8" PRIx32 , address, opcode,mnemonic, target_address);
  1175. instruction->info.b_bl_bx_blx.reg_operand = -1;
  1176. instruction->info.b_bl_bx_blx.target_address = target_address;
  1177. return ERROR_OK;
  1178. }
  1179. int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1180. {
  1181. uint8_t Rd = (opcode >> 0) & 0x7;
  1182. uint8_t Rn = (opcode >> 3) & 0x7;
  1183. uint8_t Rm_imm = (opcode >> 6) & 0x7;
  1184. uint32_t opc = opcode & (1 << 9);
  1185. uint32_t reg_imm = opcode & (1 << 10);
  1186. char *mnemonic;
  1187. if (opc)
  1188. {
  1189. instruction->type = ARM_SUB;
  1190. mnemonic = "SUBS";
  1191. }
  1192. else
  1193. {
  1194. instruction->type = ARM_ADD;
  1195. mnemonic = "ADDS";
  1196. }
  1197. instruction->info.data_proc.Rd = Rd;
  1198. instruction->info.data_proc.Rn = Rn;
  1199. instruction->info.data_proc.S = 1;
  1200. if (reg_imm)
  1201. {
  1202. instruction->info.data_proc.variant = 0; /*immediate*/
  1203. instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
  1204. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #%d",
  1205. address, opcode, mnemonic, Rd, Rn, Rm_imm);
  1206. }
  1207. else
  1208. {
  1209. instruction->info.data_proc.variant = 1; /*immediate shift*/
  1210. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
  1211. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, r%i",
  1212. address, opcode, mnemonic, Rd, Rn, Rm_imm);
  1213. }
  1214. return ERROR_OK;
  1215. }
  1216. int evaluate_shift_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1217. {
  1218. uint8_t Rd = (opcode >> 0) & 0x7;
  1219. uint8_t Rm = (opcode >> 3) & 0x7;
  1220. uint8_t imm = (opcode >> 6) & 0x1f;
  1221. uint8_t opc = (opcode >> 11) & 0x3;
  1222. char *mnemonic = NULL;
  1223. switch (opc)
  1224. {
  1225. case 0:
  1226. instruction->type = ARM_MOV;
  1227. mnemonic = "LSLS";
  1228. instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
  1229. break;
  1230. case 1:
  1231. instruction->type = ARM_MOV;
  1232. mnemonic = "LSRS";
  1233. instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
  1234. break;
  1235. case 2:
  1236. instruction->type = ARM_MOV;
  1237. mnemonic = "ASRS";
  1238. instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
  1239. break;
  1240. }
  1241. if ((imm == 0) && (opc != 0))
  1242. imm = 32;
  1243. instruction->info.data_proc.Rd = Rd;
  1244. instruction->info.data_proc.Rn = -1;
  1245. instruction->info.data_proc.S = 1;
  1246. instruction->info.data_proc.variant = 1; /*immediate_shift*/
  1247. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
  1248. instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
  1249. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #0x%02x" ,
  1250. address, opcode, mnemonic, Rd, Rm, imm);
  1251. return ERROR_OK;
  1252. }
  1253. int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1254. {
  1255. uint8_t imm = opcode & 0xff;
  1256. uint8_t Rd = (opcode >> 8) & 0x7;
  1257. uint32_t opc = (opcode >> 11) & 0x3;
  1258. char *mnemonic = NULL;
  1259. instruction->info.data_proc.Rd = Rd;
  1260. instruction->info.data_proc.Rn = Rd;
  1261. instruction->info.data_proc.S = 1;
  1262. instruction->info.data_proc.variant = 0; /*immediate*/
  1263. instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
  1264. switch (opc)
  1265. {
  1266. case 0:
  1267. instruction->type = ARM_MOV;
  1268. mnemonic = "MOVS";
  1269. instruction->info.data_proc.Rn = -1;
  1270. break;
  1271. case 1:
  1272. instruction->type = ARM_CMP;
  1273. mnemonic = "CMP";
  1274. instruction->info.data_proc.Rd = -1;
  1275. break;
  1276. case 2:
  1277. instruction->type = ARM_ADD;
  1278. mnemonic = "ADDS";
  1279. break;
  1280. case 3:
  1281. instruction->type = ARM_SUB;
  1282. mnemonic = "SUBS";
  1283. break;
  1284. }
  1285. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, #0x%02x" ,
  1286. address, opcode, mnemonic, Rd, imm);
  1287. return ERROR_OK;
  1288. }
  1289. int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1290. {
  1291. uint8_t high_reg, op, Rm, Rd,H1,H2;
  1292. char *mnemonic = NULL;
  1293. high_reg = (opcode & 0x0400) >> 10;
  1294. op = (opcode & 0x03C0) >> 6;
  1295. Rd = (opcode & 0x0007);
  1296. Rm = (opcode & 0x0038) >> 3;
  1297. H1 = (opcode & 0x0080) >> 7;
  1298. H2 = (opcode & 0x0040) >> 6;
  1299. instruction->info.data_proc.Rd = Rd;
  1300. instruction->info.data_proc.Rn = Rd;
  1301. instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
  1302. instruction->info.data_proc.variant = 1 /*immediate shift*/;
  1303. instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
  1304. if (high_reg)
  1305. {
  1306. Rd |= H1 << 3;
  1307. Rm |= H2 << 3;
  1308. op >>= 2;
  1309. switch (op)
  1310. {
  1311. case 0x0:
  1312. instruction->type = ARM_ADD;
  1313. mnemonic = "ADD";
  1314. break;
  1315. case 0x1:
  1316. instruction->type = ARM_CMP;
  1317. mnemonic = "CMP";
  1318. break;
  1319. case 0x2:
  1320. instruction->type = ARM_MOV;
  1321. mnemonic = "MOV";
  1322. break;
  1323. case 0x3:
  1324. if ((opcode & 0x7) == 0x0)
  1325. {
  1326. instruction->info.b_bl_bx_blx.reg_operand = Rm;
  1327. if (H1)
  1328. {
  1329. instruction->type = ARM_BLX;
  1330. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBLX r%i", address, opcode, Rm);
  1331. }
  1332. else
  1333. {
  1334. instruction->type = ARM_BX;
  1335. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBX r%i", address, opcode, Rm);
  1336. }
  1337. }
  1338. else
  1339. {
  1340. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1341. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
  1342. }
  1343. return ERROR_OK;
  1344. break;
  1345. }
  1346. }
  1347. else
  1348. {
  1349. switch (op)
  1350. {
  1351. case 0x0:
  1352. instruction->type = ARM_AND;
  1353. mnemonic = "ANDS";
  1354. break;
  1355. case 0x1:
  1356. instruction->type = ARM_EOR;
  1357. mnemonic = "EORS";
  1358. break;
  1359. case 0x2:
  1360. instruction->type = ARM_MOV;
  1361. mnemonic = "LSLS";
  1362. instruction->info.data_proc.variant = 2 /*register shift*/;
  1363. instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
  1364. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1365. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1366. break;
  1367. case 0x3:
  1368. instruction->type = ARM_MOV;
  1369. mnemonic = "LSRS";
  1370. instruction->info.data_proc.variant = 2 /*register shift*/;
  1371. instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
  1372. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1373. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1374. break;
  1375. case 0x4:
  1376. instruction->type = ARM_MOV;
  1377. mnemonic = "ASRS";
  1378. instruction->info.data_proc.variant = 2 /*register shift*/;
  1379. instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
  1380. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1381. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1382. break;
  1383. case 0x5:
  1384. instruction->type = ARM_ADC;
  1385. mnemonic = "ADCS";
  1386. break;
  1387. case 0x6:
  1388. instruction->type = ARM_SBC;
  1389. mnemonic = "SBCS";
  1390. break;
  1391. case 0x7:
  1392. instruction->type = ARM_MOV;
  1393. mnemonic = "RORS";
  1394. instruction->info.data_proc.variant = 2 /*register shift*/;
  1395. instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
  1396. instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
  1397. instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
  1398. break;
  1399. case 0x8:
  1400. instruction->type = ARM_TST;
  1401. mnemonic = "TST";
  1402. break;
  1403. case 0x9:
  1404. instruction->type = ARM_RSB;
  1405. mnemonic = "NEGS";
  1406. instruction->info.data_proc.variant = 0 /*immediate*/;
  1407. instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
  1408. instruction->info.data_proc.Rn = Rm;
  1409. break;
  1410. case 0xA:
  1411. instruction->type = ARM_CMP;
  1412. mnemonic = "CMP";
  1413. break;
  1414. case 0xB:
  1415. instruction->type = ARM_CMN;
  1416. mnemonic = "CMN";
  1417. break;
  1418. case 0xC:
  1419. instruction->type = ARM_ORR;
  1420. mnemonic = "ORRS";
  1421. break;
  1422. case 0xD:
  1423. instruction->type = ARM_MUL;
  1424. mnemonic = "MULS";
  1425. break;
  1426. case 0xE:
  1427. instruction->type = ARM_BIC;
  1428. mnemonic = "BICS";
  1429. break;
  1430. case 0xF:
  1431. instruction->type = ARM_MVN;
  1432. mnemonic = "MVNS";
  1433. break;
  1434. }
  1435. }
  1436. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i",
  1437. address, opcode, mnemonic, Rd, Rm);
  1438. return ERROR_OK;
  1439. }
  1440. int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1441. {
  1442. uint32_t immediate;
  1443. uint8_t Rd = (opcode >> 8) & 0x7;
  1444. instruction->type = ARM_LDR;
  1445. immediate = opcode & 0x000000ff;
  1446. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tLDR r%i, [PC, #0x%" PRIx32 "]", address, opcode, Rd, immediate*4);
  1447. instruction->info.load_store.Rd = Rd;
  1448. instruction->info.load_store.Rn = 15 /*PC*/;
  1449. instruction->info.load_store.index_mode = 0; /*offset*/
  1450. instruction->info.load_store.offset_mode = 0; /*immediate*/
  1451. instruction->info.load_store.offset.offset = immediate*4;
  1452. return ERROR_OK;
  1453. }
  1454. int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1455. {
  1456. uint8_t Rd = (opcode >> 0) & 0x7;
  1457. uint8_t Rn = (opcode >> 3) & 0x7;
  1458. uint8_t Rm = (opcode >> 6) & 0x7;
  1459. uint8_t opc = (opcode >> 9) & 0x7;
  1460. char *mnemonic = NULL;
  1461. switch (opc)
  1462. {
  1463. case 0:
  1464. instruction->type = ARM_STR;
  1465. mnemonic = "STR";
  1466. break;
  1467. case 1:
  1468. instruction->type = ARM_STRH;
  1469. mnemonic = "STRH";
  1470. break;
  1471. case 2:
  1472. instruction->type = ARM_STRB;
  1473. mnemonic = "STRB";
  1474. break;
  1475. case 3:
  1476. instruction->type = ARM_LDRSB;
  1477. mnemonic = "LDRSB";
  1478. break;
  1479. case 4:
  1480. instruction->type = ARM_LDR;
  1481. mnemonic = "LDR";
  1482. break;
  1483. case 5:
  1484. instruction->type = ARM_LDRH;
  1485. mnemonic = "LDRH";
  1486. break;
  1487. case 6:
  1488. instruction->type = ARM_LDRB;
  1489. mnemonic = "LDRB";
  1490. break;
  1491. case 7:
  1492. instruction->type = ARM_LDRSH;
  1493. mnemonic = "LDRSH";
  1494. break;
  1495. }
  1496. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [r%i, r%i]", address, opcode, mnemonic, Rd, Rn, Rm);
  1497. instruction->info.load_store.Rd = Rd;
  1498. instruction->info.load_store.Rn = Rn;
  1499. instruction->info.load_store.index_mode = 0; /*offset*/
  1500. instruction->info.load_store.offset_mode = 1; /*register*/
  1501. instruction->info.load_store.offset.reg.Rm = Rm;
  1502. return ERROR_OK;
  1503. }
  1504. int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1505. {
  1506. uint32_t offset = (opcode >> 6) & 0x1f;
  1507. uint8_t Rd = (opcode >> 0) & 0x7;
  1508. uint8_t Rn = (opcode >> 3) & 0x7;
  1509. uint32_t L = opcode & (1 << 11);
  1510. uint32_t B = opcode & (1 << 12);
  1511. char *mnemonic;
  1512. char suffix = ' ';
  1513. uint32_t shift = 2;
  1514. if (L)
  1515. {
  1516. instruction->type = ARM_LDR;
  1517. mnemonic = "LDR";
  1518. }
  1519. else
  1520. {
  1521. instruction->type = ARM_STR;
  1522. mnemonic = "STR";
  1523. }
  1524. if ((opcode&0xF000) == 0x8000)
  1525. {
  1526. suffix = 'H';
  1527. shift = 1;
  1528. }
  1529. else if (B)
  1530. {
  1531. suffix = 'B';
  1532. shift = 0;
  1533. }
  1534. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s%c r%i, [r%i, #0x%" PRIx32 "]", address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
  1535. instruction->info.load_store.Rd = Rd;
  1536. instruction->info.load_store.Rn = Rn;
  1537. instruction->info.load_store.index_mode = 0; /*offset*/
  1538. instruction->info.load_store.offset_mode = 0; /*immediate*/
  1539. instruction->info.load_store.offset.offset = offset << shift;
  1540. return ERROR_OK;
  1541. }
  1542. int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1543. {
  1544. uint32_t offset = opcode & 0xff;
  1545. uint8_t Rd = (opcode >> 8) & 0x7;
  1546. uint32_t L = opcode & (1 << 11);
  1547. char *mnemonic;
  1548. if (L)
  1549. {
  1550. instruction->type = ARM_LDR;
  1551. mnemonic = "LDR";
  1552. }
  1553. else
  1554. {
  1555. instruction->type = ARM_STR;
  1556. mnemonic = "STR";
  1557. }
  1558. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [SP, #0x%" PRIx32 "]", address, opcode, mnemonic, Rd, offset*4);
  1559. instruction->info.load_store.Rd = Rd;
  1560. instruction->info.load_store.Rn = 13 /*SP*/;
  1561. instruction->info.load_store.index_mode = 0; /*offset*/
  1562. instruction->info.load_store.offset_mode = 0; /*immediate*/
  1563. instruction->info.load_store.offset.offset = offset*4;
  1564. return ERROR_OK;
  1565. }
  1566. int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1567. {
  1568. uint32_t imm = opcode & 0xff;
  1569. uint8_t Rd = (opcode >> 8) & 0x7;
  1570. uint8_t Rn;
  1571. uint32_t SP = opcode & (1 << 11);
  1572. char *reg_name;
  1573. instruction->type = ARM_ADD;
  1574. if (SP)
  1575. {
  1576. reg_name = "SP";
  1577. Rn = 13;
  1578. }
  1579. else
  1580. {
  1581. reg_name = "PC";
  1582. Rn = 15;
  1583. }
  1584. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tADD r%i, %s, #0x%" PRIx32 "", address, opcode, Rd,reg_name, imm*4);
  1585. instruction->info.data_proc.variant = 0 /* immediate */;
  1586. instruction->info.data_proc.Rd = Rd;
  1587. instruction->info.data_proc.Rn = Rn;
  1588. instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
  1589. return ERROR_OK;
  1590. }
  1591. int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1592. {
  1593. uint32_t imm = opcode & 0x7f;
  1594. uint8_t opc = opcode & (1 << 7);
  1595. char *mnemonic;
  1596. if (opc)
  1597. {
  1598. instruction->type = ARM_SUB;
  1599. mnemonic = "SUB";
  1600. }
  1601. else
  1602. {
  1603. instruction->type = ARM_ADD;
  1604. mnemonic = "ADD";
  1605. }
  1606. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s SP, #0x%" PRIx32 "", address, opcode, mnemonic, imm*4);
  1607. instruction->info.data_proc.variant = 0 /* immediate */;
  1608. instruction->info.data_proc.Rd = 13 /*SP*/;
  1609. instruction->info.data_proc.Rn = 13 /*SP*/;
  1610. instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
  1611. return ERROR_OK;
  1612. }
  1613. int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1614. {
  1615. uint32_t imm = opcode & 0xff;
  1616. instruction->type = ARM_BKPT;
  1617. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBKPT 0x%02" PRIx32 "", address, opcode, imm);
  1618. return ERROR_OK;
  1619. }
  1620. int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1621. {
  1622. uint32_t reg_list = opcode & 0xff;
  1623. uint32_t L = opcode & (1 << 11);
  1624. uint32_t R = opcode & (1 << 8);
  1625. uint8_t Rn = (opcode >> 8) & 7;
  1626. uint8_t addr_mode = 0 /* IA */;
  1627. char reg_names[40];
  1628. char *reg_names_p;
  1629. char *mnemonic;
  1630. char ptr_name[7] = "";
  1631. int i;
  1632. if ((opcode & 0xf000) == 0xc000)
  1633. { /* generic load/store multiple */
  1634. if (L)
  1635. {
  1636. instruction->type = ARM_LDM;
  1637. mnemonic = "LDMIA";
  1638. }
  1639. else
  1640. {
  1641. instruction->type = ARM_STM;
  1642. mnemonic = "STMIA";
  1643. }
  1644. snprintf(ptr_name,7,"r%i!, ",Rn);
  1645. }
  1646. else
  1647. { /* push/pop */
  1648. Rn = 13; /* SP */
  1649. if (L)
  1650. {
  1651. instruction->type = ARM_LDM;
  1652. mnemonic = "POP";
  1653. if (R)
  1654. reg_list |= (1 << 15) /*PC*/;
  1655. }
  1656. else
  1657. {
  1658. instruction->type = ARM_STM;
  1659. mnemonic = "PUSH";
  1660. addr_mode = 3; /*DB*/
  1661. if (R)
  1662. reg_list |= (1 << 14) /*LR*/;
  1663. }
  1664. }
  1665. reg_names_p = reg_names;
  1666. for (i = 0; i <= 15; i++)
  1667. {
  1668. if (reg_list & (1 << i))
  1669. reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
  1670. }
  1671. if (reg_names_p > reg_names)
  1672. reg_names_p[-2] = '\0';
  1673. else /* invalid op : no registers */
  1674. reg_names[0] = '\0';
  1675. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s %s{%s}", address, opcode, mnemonic, ptr_name,reg_names);
  1676. instruction->info.load_store_multiple.register_list = reg_list;
  1677. instruction->info.load_store_multiple.Rn = Rn;
  1678. instruction->info.load_store_multiple.addressing_mode = addr_mode;
  1679. return ERROR_OK;
  1680. }
  1681. int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1682. {
  1683. uint32_t offset = opcode & 0xff;
  1684. uint8_t cond = (opcode >> 8) & 0xf;
  1685. uint32_t target_address;
  1686. if (cond == 0xf)
  1687. {
  1688. instruction->type = ARM_SWI;
  1689. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tSWI 0x%02" PRIx32 , address, opcode, offset);
  1690. return ERROR_OK;
  1691. }
  1692. else if (cond == 0xe)
  1693. {
  1694. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1695. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
  1696. return ERROR_OK;
  1697. }
  1698. /* sign extend 8-bit offset */
  1699. if (offset & 0x00000080)
  1700. offset = 0xffffff00 | offset;
  1701. target_address = address + 4 + (offset << 1);
  1702. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tB%s 0x%8.8" PRIx32 , address, opcode,
  1703. arm_condition_strings[cond], target_address);
  1704. instruction->type = ARM_B;
  1705. instruction->info.b_bl_bx_blx.reg_operand = -1;
  1706. instruction->info.b_bl_bx_blx.target_address = target_address;
  1707. return ERROR_OK;
  1708. }
  1709. int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
  1710. {
  1711. /* clear fields, to avoid confusion */
  1712. memset(instruction, 0, sizeof(arm_instruction_t));
  1713. instruction->opcode = opcode;
  1714. if ((opcode & 0xe000) == 0x0000)
  1715. {
  1716. /* add/substract register or immediate */
  1717. if ((opcode & 0x1800) == 0x1800)
  1718. return evaluate_add_sub_thumb(opcode, address, instruction);
  1719. /* shift by immediate */
  1720. else
  1721. return evaluate_shift_imm_thumb(opcode, address, instruction);
  1722. }
  1723. /* Add/substract/compare/move immediate */
  1724. if ((opcode & 0xe000) == 0x2000)
  1725. {
  1726. return evaluate_data_proc_imm_thumb(opcode, address, instruction);
  1727. }
  1728. /* Data processing instructions */
  1729. if ((opcode & 0xf800) == 0x4000)
  1730. {
  1731. return evaluate_data_proc_thumb(opcode, address, instruction);
  1732. }
  1733. /* Load from literal pool */
  1734. if ((opcode & 0xf800) == 0x4800)
  1735. {
  1736. return evaluate_load_literal_thumb(opcode, address, instruction);
  1737. }
  1738. /* Load/Store register offset */
  1739. if ((opcode & 0xf000) == 0x5000)
  1740. {
  1741. return evaluate_load_store_reg_thumb(opcode, address, instruction);
  1742. }
  1743. /* Load/Store immediate offset */
  1744. if (((opcode & 0xe000) == 0x6000)
  1745. ||((opcode & 0xf000) == 0x8000))
  1746. {
  1747. return evaluate_load_store_imm_thumb(opcode, address, instruction);
  1748. }
  1749. /* Load/Store from/to stack */
  1750. if ((opcode & 0xf000) == 0x9000)
  1751. {
  1752. return evaluate_load_store_stack_thumb(opcode, address, instruction);
  1753. }
  1754. /* Add to SP/PC */
  1755. if ((opcode & 0xf000) == 0xa000)
  1756. {
  1757. return evaluate_add_sp_pc_thumb(opcode, address, instruction);
  1758. }
  1759. /* Misc */
  1760. if ((opcode & 0xf000) == 0xb000)
  1761. {
  1762. if ((opcode & 0x0f00) == 0x0000)
  1763. return evaluate_adjust_stack_thumb(opcode, address, instruction);
  1764. else if ((opcode & 0x0f00) == 0x0e00)
  1765. return evaluate_breakpoint_thumb(opcode, address, instruction);
  1766. else if ((opcode & 0x0600) == 0x0400) /* push pop */
  1767. return evaluate_load_store_multiple_thumb(opcode, address, instruction);
  1768. else
  1769. {
  1770. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1771. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
  1772. return ERROR_OK;
  1773. }
  1774. }
  1775. /* Load/Store multiple */
  1776. if ((opcode & 0xf000) == 0xc000)
  1777. {
  1778. return evaluate_load_store_multiple_thumb(opcode, address, instruction);
  1779. }
  1780. /* Conditional branch + SWI */
  1781. if ((opcode & 0xf000) == 0xd000)
  1782. {
  1783. return evaluate_cond_branch_thumb(opcode, address, instruction);
  1784. }
  1785. if ((opcode & 0xe000) == 0xe000)
  1786. {
  1787. /* Undefined instructions */
  1788. if ((opcode & 0xf801) == 0xe801)
  1789. {
  1790. instruction->type = ARM_UNDEFINED_INSTRUCTION;
  1791. snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
  1792. return ERROR_OK;
  1793. }
  1794. else
  1795. { /* Branch to offset */
  1796. return evaluate_b_bl_blx_thumb(opcode, address, instruction);
  1797. }
  1798. }
  1799. LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
  1800. return -1;
  1801. }
  1802. int arm_access_size(arm_instruction_t *instruction)
  1803. {
  1804. if ((instruction->type == ARM_LDRB)
  1805. || (instruction->type == ARM_LDRBT)
  1806. || (instruction->type == ARM_LDRSB)
  1807. || (instruction->type == ARM_STRB)
  1808. || (instruction->type == ARM_STRBT))
  1809. {
  1810. return 1;
  1811. }
  1812. else if ((instruction->type == ARM_LDRH)
  1813. || (instruction->type == ARM_LDRSH)
  1814. || (instruction->type == ARM_STRH))
  1815. {
  1816. return 2;
  1817. }
  1818. else if ((instruction->type == ARM_LDR)
  1819. || (instruction->type == ARM_LDRT)
  1820. || (instruction->type == ARM_STR)
  1821. || (instruction->type == ARM_STRT))
  1822. {
  1823. return 4;
  1824. }
  1825. else if ((instruction->type == ARM_LDRD)
  1826. || (instruction->type == ARM_STRD))
  1827. {
  1828. return 8;
  1829. }
  1830. else
  1831. {
  1832. LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
  1833. return 0;
  1834. }
  1835. }