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.
 
 
 
 
 
 

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