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.
 
 
 
 
 
 

744 lines
20 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2006 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2008 by Hongtao Zheng *
  6. * hontor@126.com *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "armv4_5.h"
  27. #include "arm_disassembler.h"
  28. #include "arm_simulator.h"
  29. #include "log.h"
  30. #include "binarybuffer.h"
  31. uint32_t arm_shift(uint8_t shift, uint32_t Rm, uint32_t shift_amount, uint8_t *carry)
  32. {
  33. uint32_t return_value = 0;
  34. shift_amount &= 0xff;
  35. if (shift == 0x0) /* LSL */
  36. {
  37. if ((shift_amount > 0) && (shift_amount <= 32))
  38. {
  39. return_value = Rm << shift_amount;
  40. *carry = Rm >> (32 - shift_amount);
  41. }
  42. else if (shift_amount > 32)
  43. {
  44. return_value = 0x0;
  45. *carry = 0x0;
  46. }
  47. else /* (shift_amount == 0) */
  48. {
  49. return_value = Rm;
  50. }
  51. }
  52. else if (shift == 0x1) /* LSR */
  53. {
  54. if ((shift_amount > 0) && (shift_amount <= 32))
  55. {
  56. return_value = Rm >> shift_amount;
  57. *carry = (Rm >> (shift_amount - 1)) & 1;
  58. }
  59. else if (shift_amount > 32)
  60. {
  61. return_value = 0x0;
  62. *carry = 0x0;
  63. }
  64. else /* (shift_amount == 0) */
  65. {
  66. return_value = Rm;
  67. }
  68. }
  69. else if (shift == 0x2) /* ASR */
  70. {
  71. if ((shift_amount > 0) && (shift_amount <= 32))
  72. {
  73. /* right shifts of unsigned values are guaranteed to be logical (shift in zeroes)
  74. * simulate an arithmetic shift (shift in signed-bit) by adding the signed-bit manually */
  75. return_value = Rm >> shift_amount;
  76. if (Rm & 0x80000000)
  77. return_value |= 0xffffffff << (32 - shift_amount);
  78. }
  79. else if (shift_amount > 32)
  80. {
  81. if (Rm & 0x80000000)
  82. {
  83. return_value = 0xffffffff;
  84. *carry = 0x1;
  85. }
  86. else
  87. {
  88. return_value = 0x0;
  89. *carry = 0x0;
  90. }
  91. }
  92. else /* (shift_amount == 0) */
  93. {
  94. return_value = Rm;
  95. }
  96. }
  97. else if (shift == 0x3) /* ROR */
  98. {
  99. if (shift_amount == 0)
  100. {
  101. return_value = Rm;
  102. }
  103. else
  104. {
  105. shift_amount = shift_amount % 32;
  106. return_value = (Rm >> shift_amount) | (Rm << (32 - shift_amount));
  107. *carry = (return_value >> 31) & 0x1;
  108. }
  109. }
  110. else if (shift == 0x4) /* RRX */
  111. {
  112. return_value = Rm >> 1;
  113. if (*carry)
  114. Rm |= 0x80000000;
  115. *carry = Rm & 0x1;
  116. }
  117. return return_value;
  118. }
  119. uint32_t arm_shifter_operand(armv4_5_common_t *armv4_5, int variant, union arm_shifter_operand shifter_operand, uint8_t *shifter_carry_out)
  120. {
  121. uint32_t return_value;
  122. int instruction_size;
  123. if (armv4_5->core_state == ARMV4_5_STATE_ARM)
  124. instruction_size = 4;
  125. else
  126. instruction_size = 2;
  127. *shifter_carry_out = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
  128. if (variant == 0) /* 32-bit immediate */
  129. {
  130. return_value = shifter_operand.immediate.immediate;
  131. }
  132. else if (variant == 1) /* immediate shift */
  133. {
  134. uint32_t Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.immediate_shift.Rm).value, 0, 32);
  135. /* adjust RM in case the PC is being read */
  136. if (shifter_operand.immediate_shift.Rm == 15)
  137. Rm += 2 * instruction_size;
  138. return_value = arm_shift(shifter_operand.immediate_shift.shift, Rm, shifter_operand.immediate_shift.shift_imm, shifter_carry_out);
  139. }
  140. else if (variant == 2) /* register shift */
  141. {
  142. uint32_t Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.register_shift.Rm).value, 0, 32);
  143. uint32_t Rs = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, shifter_operand.register_shift.Rs).value, 0, 32);
  144. /* adjust RM in case the PC is being read */
  145. if (shifter_operand.register_shift.Rm == 15)
  146. Rm += 2 * instruction_size;
  147. return_value = arm_shift(shifter_operand.immediate_shift.shift, Rm, Rs, shifter_carry_out);
  148. }
  149. else
  150. {
  151. LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2");
  152. return_value = 0xffffffff;
  153. }
  154. return return_value;
  155. }
  156. int pass_condition(uint32_t cpsr, uint32_t opcode)
  157. {
  158. switch ((opcode & 0xf0000000) >> 28)
  159. {
  160. case 0x0: /* EQ */
  161. if (cpsr & 0x40000000)
  162. return 1;
  163. else
  164. return 0;
  165. case 0x1: /* NE */
  166. if (!(cpsr & 0x40000000))
  167. return 1;
  168. else
  169. return 0;
  170. case 0x2: /* CS */
  171. if (cpsr & 0x20000000)
  172. return 1;
  173. else
  174. return 0;
  175. case 0x3: /* CC */
  176. if (!(cpsr & 0x20000000))
  177. return 1;
  178. else
  179. return 0;
  180. case 0x4: /* MI */
  181. if (cpsr & 0x80000000)
  182. return 1;
  183. else
  184. return 0;
  185. case 0x5: /* PL */
  186. if (!(cpsr & 0x80000000))
  187. return 1;
  188. else
  189. return 0;
  190. case 0x6: /* VS */
  191. if (cpsr & 0x10000000)
  192. return 1;
  193. else
  194. return 0;
  195. case 0x7: /* VC */
  196. if (!(cpsr & 0x10000000))
  197. return 1;
  198. else
  199. return 0;
  200. case 0x8: /* HI */
  201. if ((cpsr & 0x20000000) && !(cpsr & 0x40000000))
  202. return 1;
  203. else
  204. return 0;
  205. case 0x9: /* LS */
  206. if (!(cpsr & 0x20000000) || (cpsr & 0x40000000))
  207. return 1;
  208. else
  209. return 0;
  210. case 0xa: /* GE */
  211. if (((cpsr & 0x80000000) && (cpsr & 0x10000000))
  212. || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000)))
  213. return 1;
  214. else
  215. return 0;
  216. case 0xb: /* LT */
  217. if (((cpsr & 0x80000000) && !(cpsr & 0x10000000))
  218. || (!(cpsr & 0x80000000) && (cpsr & 0x10000000)))
  219. return 1;
  220. else
  221. return 0;
  222. case 0xc: /* GT */
  223. if (!(cpsr & 0x40000000) &&
  224. (((cpsr & 0x80000000) && (cpsr & 0x10000000))
  225. || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000))))
  226. return 1;
  227. else
  228. return 0;
  229. case 0xd: /* LE */
  230. if ((cpsr & 0x40000000) &&
  231. (((cpsr & 0x80000000) && !(cpsr & 0x10000000))
  232. || (!(cpsr & 0x80000000) && (cpsr & 0x10000000))))
  233. return 1;
  234. else
  235. return 0;
  236. case 0xe:
  237. case 0xf:
  238. return 1;
  239. }
  240. LOG_ERROR("BUG: should never get here");
  241. return 0;
  242. }
  243. int thumb_pass_branch_condition(uint32_t cpsr, uint16_t opcode)
  244. {
  245. return pass_condition(cpsr, (opcode & 0x0f00) << 20);
  246. }
  247. /* simulate a single step (if possible)
  248. * if the dry_run_pc argument is provided, no state is changed,
  249. * but the new pc is stored in the variable pointed at by the argument
  250. */
  251. int arm_simulate_step(target_t *target, uint32_t *dry_run_pc)
  252. {
  253. armv4_5_common_t *armv4_5 = target->arch_info;
  254. uint32_t current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
  255. arm_instruction_t instruction;
  256. int instruction_size;
  257. int retval = ERROR_OK;
  258. if (armv4_5->core_state == ARMV4_5_STATE_ARM)
  259. {
  260. uint32_t opcode;
  261. /* get current instruction, and identify it */
  262. if ((retval = target_read_u32(target, current_pc, &opcode)) != ERROR_OK)
  263. {
  264. return retval;
  265. }
  266. if ((retval = arm_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK)
  267. {
  268. return retval;
  269. }
  270. instruction_size = 4;
  271. /* check condition code (for all instructions) */
  272. if (!pass_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode))
  273. {
  274. if (dry_run_pc)
  275. {
  276. *dry_run_pc = current_pc + instruction_size;
  277. }
  278. else
  279. {
  280. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
  281. }
  282. return ERROR_OK;
  283. }
  284. }
  285. else
  286. {
  287. uint16_t opcode;
  288. if ((retval = target_read_u16(target, current_pc, &opcode)) != ERROR_OK)
  289. {
  290. return retval;
  291. }
  292. if ((retval = thumb_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK)
  293. {
  294. return retval;
  295. }
  296. instruction_size = 2;
  297. /* check condition code (only for branch instructions) */
  298. if ((!thumb_pass_branch_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode)) &&
  299. (instruction.type == ARM_B))
  300. {
  301. if (dry_run_pc)
  302. {
  303. *dry_run_pc = current_pc + instruction_size;
  304. }
  305. else
  306. {
  307. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
  308. }
  309. return ERROR_OK;
  310. }
  311. }
  312. /* examine instruction type */
  313. /* branch instructions */
  314. if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX))
  315. {
  316. uint32_t target;
  317. if (instruction.info.b_bl_bx_blx.reg_operand == -1)
  318. {
  319. target = instruction.info.b_bl_bx_blx.target_address;
  320. }
  321. else
  322. {
  323. target = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.b_bl_bx_blx.reg_operand).value, 0, 32);
  324. if (instruction.info.b_bl_bx_blx.reg_operand == 15)
  325. {
  326. target += 2 * instruction_size;
  327. }
  328. }
  329. if (dry_run_pc)
  330. {
  331. *dry_run_pc = target;
  332. return ERROR_OK;
  333. }
  334. else
  335. {
  336. if (instruction.type == ARM_B)
  337. {
  338. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target);
  339. }
  340. else if (instruction.type == ARM_BL)
  341. {
  342. uint32_t old_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
  343. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 14).value, 0, 32, old_pc + 4);
  344. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target);
  345. }
  346. else if (instruction.type == ARM_BX)
  347. {
  348. if (target & 0x1)
  349. {
  350. armv4_5->core_state = ARMV4_5_STATE_THUMB;
  351. }
  352. else
  353. {
  354. armv4_5->core_state = ARMV4_5_STATE_ARM;
  355. }
  356. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target & 0xfffffffe);
  357. }
  358. else if (instruction.type == ARM_BLX)
  359. {
  360. uint32_t old_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
  361. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 14).value, 0, 32, old_pc + 4);
  362. if (target & 0x1)
  363. {
  364. armv4_5->core_state = ARMV4_5_STATE_THUMB;
  365. }
  366. else
  367. {
  368. armv4_5->core_state = ARMV4_5_STATE_ARM;
  369. }
  370. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, target & 0xfffffffe);
  371. }
  372. return ERROR_OK;
  373. }
  374. }
  375. /* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */
  376. else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC))
  377. || ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN)))
  378. {
  379. uint32_t Rd, Rn, shifter_operand;
  380. uint8_t C = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
  381. uint8_t carry_out;
  382. Rd = 0x0;
  383. /* ARM_MOV and ARM_MVN does not use Rn */
  384. if ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN))
  385. Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rn).value, 0, 32);
  386. else
  387. Rn = 0;
  388. shifter_operand = arm_shifter_operand(armv4_5, instruction.info.data_proc.variant, instruction.info.data_proc.shifter_operand, &carry_out);
  389. /* adjust Rn in case the PC is being read */
  390. if (instruction.info.data_proc.Rn == 15)
  391. Rn += 2 * instruction_size;
  392. if (instruction.type == ARM_AND)
  393. Rd = Rn & shifter_operand;
  394. else if (instruction.type == ARM_EOR)
  395. Rd = Rn ^ shifter_operand;
  396. else if (instruction.type == ARM_SUB)
  397. Rd = Rn - shifter_operand;
  398. else if (instruction.type == ARM_RSB)
  399. Rd = shifter_operand - Rn;
  400. else if (instruction.type == ARM_ADD)
  401. Rd = Rn + shifter_operand;
  402. else if (instruction.type == ARM_ADC)
  403. Rd = Rn + shifter_operand + (C & 1);
  404. else if (instruction.type == ARM_SBC)
  405. Rd = Rn - shifter_operand - (C & 1) ? 0 : 1;
  406. else if (instruction.type == ARM_RSC)
  407. Rd = shifter_operand - Rn - (C & 1) ? 0 : 1;
  408. else if (instruction.type == ARM_ORR)
  409. Rd = Rn | shifter_operand;
  410. else if (instruction.type == ARM_BIC)
  411. Rd = Rn & ~(shifter_operand);
  412. else if (instruction.type == ARM_MOV)
  413. Rd = shifter_operand;
  414. else if (instruction.type == ARM_MVN)
  415. Rd = ~shifter_operand;
  416. else
  417. LOG_WARNING("unhandled instruction type");
  418. if (dry_run_pc)
  419. {
  420. if (instruction.info.data_proc.Rd == 15)
  421. {
  422. *dry_run_pc = Rd;
  423. return ERROR_OK;
  424. }
  425. else
  426. {
  427. *dry_run_pc = current_pc + instruction_size;
  428. }
  429. return ERROR_OK;
  430. }
  431. else
  432. {
  433. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.data_proc.Rd).value, 0, 32, Rd);
  434. LOG_WARNING("no updating of flags yet");
  435. if (instruction.info.data_proc.Rd == 15)
  436. return ERROR_OK;
  437. }
  438. }
  439. /* compare instructions (CMP, CMN, TST, TEQ) */
  440. else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN))
  441. {
  442. if (dry_run_pc)
  443. {
  444. *dry_run_pc = current_pc + instruction_size;
  445. return ERROR_OK;
  446. }
  447. else
  448. {
  449. LOG_WARNING("no updating of flags yet");
  450. }
  451. }
  452. /* load register instructions */
  453. else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
  454. {
  455. uint32_t load_address = 0, modified_address = 0, load_value;
  456. uint32_t Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rn).value, 0, 32);
  457. /* adjust Rn in case the PC is being read */
  458. if (instruction.info.load_store.Rn == 15)
  459. Rn += 2 * instruction_size;
  460. if (instruction.info.load_store.offset_mode == 0)
  461. {
  462. if (instruction.info.load_store.U)
  463. modified_address = Rn + instruction.info.load_store.offset.offset;
  464. else
  465. modified_address = Rn - instruction.info.load_store.offset.offset;
  466. }
  467. else if (instruction.info.load_store.offset_mode == 1)
  468. {
  469. uint32_t offset;
  470. uint32_t Rm = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.offset.reg.Rm).value, 0, 32);
  471. uint8_t shift = instruction.info.load_store.offset.reg.shift;
  472. uint8_t shift_imm = instruction.info.load_store.offset.reg.shift_imm;
  473. uint8_t carry = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 29, 1);
  474. offset = arm_shift(shift, Rm, shift_imm, &carry);
  475. if (instruction.info.load_store.U)
  476. modified_address = Rn + offset;
  477. else
  478. modified_address = Rn - offset;
  479. }
  480. else
  481. {
  482. LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)");
  483. }
  484. if (instruction.info.load_store.index_mode == 0)
  485. {
  486. /* offset mode
  487. * we load from the modified address, but don't change the base address register */
  488. load_address = modified_address;
  489. modified_address = Rn;
  490. }
  491. else if (instruction.info.load_store.index_mode == 1)
  492. {
  493. /* pre-indexed mode
  494. * we load from the modified address, and write it back to the base address register */
  495. load_address = modified_address;
  496. }
  497. else if (instruction.info.load_store.index_mode == 2)
  498. {
  499. /* post-indexed mode
  500. * we load from the unmodified address, and write the modified address back */
  501. load_address = Rn;
  502. }
  503. if ((!dry_run_pc) || (instruction.info.load_store.Rd == 15))
  504. {
  505. if ((retval = target_read_u32(target, load_address, &load_value)) != ERROR_OK)
  506. {
  507. return retval;
  508. }
  509. }
  510. if (dry_run_pc)
  511. {
  512. if (instruction.info.load_store.Rd == 15)
  513. {
  514. *dry_run_pc = load_value;
  515. return ERROR_OK;
  516. }
  517. else
  518. {
  519. *dry_run_pc = current_pc + instruction_size;
  520. }
  521. return ERROR_OK;
  522. }
  523. else
  524. {
  525. if ((instruction.info.load_store.index_mode == 1) ||
  526. (instruction.info.load_store.index_mode == 2))
  527. {
  528. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rn).value, 0, 32, modified_address);
  529. }
  530. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store.Rd).value, 0, 32, load_value);
  531. if (instruction.info.load_store.Rd == 15)
  532. return ERROR_OK;
  533. }
  534. }
  535. /* load multiple instruction */
  536. else if (instruction.type == ARM_LDM)
  537. {
  538. int i;
  539. uint32_t Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32);
  540. uint32_t load_values[16];
  541. int bits_set = 0;
  542. for (i = 0; i < 16; i++)
  543. {
  544. if (instruction.info.load_store_multiple.register_list & (1 << i))
  545. bits_set++;
  546. }
  547. switch (instruction.info.load_store_multiple.addressing_mode)
  548. {
  549. case 0: /* Increment after */
  550. Rn = Rn;
  551. break;
  552. case 1: /* Increment before */
  553. Rn = Rn + 4;
  554. break;
  555. case 2: /* Decrement after */
  556. Rn = Rn - (bits_set * 4) + 4;
  557. break;
  558. case 3: /* Decrement before */
  559. Rn = Rn - (bits_set * 4);
  560. break;
  561. }
  562. for (i = 0; i < 16; i++)
  563. {
  564. if (instruction.info.load_store_multiple.register_list & (1 << i))
  565. {
  566. if ((!dry_run_pc) || (i == 15))
  567. {
  568. target_read_u32(target, Rn, &load_values[i]);
  569. }
  570. Rn += 4;
  571. }
  572. }
  573. if (dry_run_pc)
  574. {
  575. if (instruction.info.load_store_multiple.register_list & 0x8000)
  576. {
  577. *dry_run_pc = load_values[15];
  578. return ERROR_OK;
  579. }
  580. }
  581. else
  582. {
  583. enum armv4_5_mode mode = armv4_5->core_mode;
  584. int update_cpsr = 0;
  585. if (instruction.info.load_store_multiple.S)
  586. {
  587. if (instruction.info.load_store_multiple.register_list & 0x8000)
  588. update_cpsr = 1;
  589. else
  590. mode = ARMV4_5_MODE_USR;
  591. }
  592. for (i = 0; i < 16; i++)
  593. {
  594. if (instruction.info.load_store_multiple.register_list & (1 << i))
  595. {
  596. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, i).value, 0, 32, load_values[i]);
  597. }
  598. }
  599. if (update_cpsr)
  600. {
  601. uint32_t spsr = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32);
  602. buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, spsr);
  603. }
  604. /* base register writeback */
  605. if (instruction.info.load_store_multiple.W)
  606. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
  607. if (instruction.info.load_store_multiple.register_list & 0x8000)
  608. return ERROR_OK;
  609. }
  610. }
  611. /* store multiple instruction */
  612. else if (instruction.type == ARM_STM)
  613. {
  614. int i;
  615. if (dry_run_pc)
  616. {
  617. /* STM wont affect PC (advance by instruction size */
  618. }
  619. else
  620. {
  621. uint32_t Rn = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32);
  622. int bits_set = 0;
  623. enum armv4_5_mode mode = armv4_5->core_mode;
  624. for (i = 0; i < 16; i++)
  625. {
  626. if (instruction.info.load_store_multiple.register_list & (1 << i))
  627. bits_set++;
  628. }
  629. if (instruction.info.load_store_multiple.S)
  630. {
  631. mode = ARMV4_5_MODE_USR;
  632. }
  633. switch (instruction.info.load_store_multiple.addressing_mode)
  634. {
  635. case 0: /* Increment after */
  636. Rn = Rn;
  637. break;
  638. case 1: /* Increment before */
  639. Rn = Rn + 4;
  640. break;
  641. case 2: /* Decrement after */
  642. Rn = Rn - (bits_set * 4) + 4;
  643. break;
  644. case 3: /* Decrement before */
  645. Rn = Rn - (bits_set * 4);
  646. break;
  647. }
  648. for (i = 0; i < 16; i++)
  649. {
  650. if (instruction.info.load_store_multiple.register_list & (1 << i))
  651. {
  652. target_write_u32(target, Rn, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32));
  653. Rn += 4;
  654. }
  655. }
  656. /* base register writeback */
  657. if (instruction.info.load_store_multiple.W)
  658. buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, instruction.info.load_store_multiple.Rn).value, 0, 32, Rn);
  659. }
  660. }
  661. else if (!dry_run_pc)
  662. {
  663. /* the instruction wasn't handled, but we're supposed to simulate it
  664. */
  665. return ERROR_ARM_SIMULATOR_NOT_IMPLEMENTED;
  666. }
  667. if (dry_run_pc)
  668. {
  669. *dry_run_pc = current_pc + instruction_size;
  670. return ERROR_OK;
  671. }
  672. else
  673. {
  674. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
  675. return ERROR_OK;
  676. }
  677. }