X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm_disassembler.c;h=36566c9932ec725a52814100e1fbfceb5429cdec;hp=ee087b1215372f044b79db41b003518b2102980e;hb=f6315d5e5b7b71515ef051711e5f818a42d6b3b3;hpb=39dd68bca649e9275c602fa212f448ae8497f306 diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index ee087b1215..36566c9932 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -25,7 +25,7 @@ #include "target.h" #include "arm_disassembler.h" -#include "log.h" +#include /* @@ -50,6 +50,7 @@ * except as coprocessor 10/11 operations * * Most ARM instructions through ARMv6 are decoded, but some * of the post-ARMv4 opcodes may not be handled yet + * CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ... * * NEON instructions are not understood (ARMv7-A) * * - Thumb/Thumb2 decoding @@ -106,8 +107,18 @@ static uint32_t ror(uint32_t value, int places) return (value >> places) | (value << (32 - places)); } +static int evaluate_unknown(uint32_t opcode, + uint32_t address, struct arm_instruction *instruction) +{ + instruction->type = ARM_UNDEFINED_INSTRUCTION; + snprintf(instruction->text, 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 + "\tUNDEFINED INSTRUCTION", address, opcode); + return ERROR_OK; +} + static int evaluate_pld(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { /* PLD */ if ((opcode & 0x0d70f000) == 0x0550f000) @@ -118,18 +129,55 @@ static int evaluate_pld(uint32_t opcode, return ERROR_OK; } - else - { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - return ERROR_OK; + return evaluate_unknown(opcode, address, instruction); +} + +static int evaluate_srs(uint32_t opcode, + uint32_t address, struct arm_instruction *instruction) +{ + const char *wback = (opcode & (1 << 21)) ? "!" : ""; + const char *mode = ""; + + switch ((opcode >> 23) & 0x3) { + case 0: + mode = "DA"; + break; + case 1: + /* "IA" is default */ + break; + case 2: + mode = "DB"; + break; + case 3: + mode = "IB"; + break; } - LOG_ERROR("should never reach this point"); - return -1; + switch (opcode & 0x0e500000) { + case 0x08400000: + snprintf(instruction->text, 128, "0x%8.8" PRIx32 + "\t0x%8.8" PRIx32 + "\tSRS%s\tSP%s, #%d", + address, opcode, + mode, wback, + (unsigned)(opcode & 0x1f)); + break; + case 0x08100000: + snprintf(instruction->text, 128, "0x%8.8" PRIx32 + "\t0x%8.8" PRIx32 + "\tRFE%s\tr%d%s", + address, opcode, + mode, + (unsigned)((opcode >> 16) & 0xf), wback); + break; + default: + return evaluate_unknown(opcode, address, instruction); + } + return ERROR_OK; } static int evaluate_swi(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { instruction->type = ARM_SWI; @@ -141,7 +189,7 @@ static int evaluate_swi(uint32_t opcode, } static int evaluate_blx_imm(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { int offset; uint32_t immediate; @@ -174,7 +222,7 @@ static int evaluate_blx_imm(uint32_t opcode, } static int evaluate_b_bl(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t L; uint32_t immediate; @@ -212,7 +260,7 @@ static int evaluate_b_bl(uint32_t opcode, /* Coprocessor load/store and double register transfers */ /* both normal and extended instruction space (condition field b1111) */ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t cp_num = (opcode & 0xf00) >> 8; @@ -241,19 +289,24 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, mnemonic = "MRRC"; } - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, %x, r%i, r%i, c%i", - address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm); + snprintf(instruction->text, 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 + "\t%s%s%s p%i, %x, r%i, r%i, c%i", + address, opcode, mnemonic, + ((opcode & 0xf0000000) == 0xf0000000) + ? "2" : COND(opcode), + COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm); } else /* LDC or STC */ { uint8_t CRd, Rn, offset; - uint8_t U, N; + uint8_t U; char *mnemonic; char addressing_mode[32]; CRd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; - offset = (opcode & 0xff); + offset = (opcode & 0xff) << 2; /* load/store */ if (opcode & 0x00100000) @@ -268,22 +321,29 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, } U = (opcode & 0x00800000) >> 23; - N = (opcode & 0x00400000) >> 22; /* addressing modes */ - if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */ - snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x01200000) /* immediate pre-indexed */ - snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]!", Rn, (U) ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x00200000) /* immediate post-indexed */ - snprintf(addressing_mode, 32, "[r%i], #%s0x%2.2x*4", Rn, (U) ? "" : "-", offset); + if ((opcode & 0x01200000) == 0x01000000) /* offset */ + snprintf(addressing_mode, 32, "[r%i, #%s%d]", + Rn, U ? "" : "-", offset); + else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */ + snprintf(addressing_mode, 32, "[r%i, #%s%d]!", + Rn, U ? "" : "-", offset); + else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */ + snprintf(addressing_mode, 32, "[r%i], #%s%d", + Rn, U ? "" : "-", offset); else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */ - snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset); + snprintf(addressing_mode, 32, "[r%i], {%d}", + Rn, offset >> 2); - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s p%i, c%i, %s", - address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) ? COND(opcode) : "2", - (N) ? "L" : "", - cp_num, CRd, addressing_mode); + snprintf(instruction->text, 128, "0x%8.8" PRIx32 + "\t0x%8.8" PRIx32 + "\t%s%s%s p%i, c%i, %s", + address, opcode, mnemonic, + ((opcode & 0xf0000000) == 0xf0000000) + ? "2" : COND(opcode), + (opcode & (1 << 22)) ? "L" : "", + cp_num, CRd, addressing_mode); } return ERROR_OK; @@ -293,7 +353,7 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, /* Coprocessor register transfer instructions */ /* both normal and extended instruction space (condition field b1111) */ static int evaluate_cdp_mcr_mrc(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { const char *cond; char* mnemonic; @@ -343,7 +403,7 @@ static int evaluate_cdp_mcr_mrc(uint32_t opcode, /* Load/store instructions */ static int evaluate_load_store(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t I, P, U, B, W, L; uint8_t Rn, Rd; @@ -634,7 +694,7 @@ undef: /* ARMv6 and later support "media" instructions (includes SIMD) */ static int evaluate_media(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { char *cp = instruction->text; char *mnemonic = NULL; @@ -829,7 +889,7 @@ undef: /* Miscellaneous load/store instructions */ static int evaluate_misc_load_store(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t P, U, I, W, L, S, H; uint8_t Rn, Rd; @@ -957,7 +1017,7 @@ static int evaluate_misc_load_store(uint32_t opcode, /* Load/store multiples instructions */ static int evaluate_ldm_stm(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t P, U, S, W, L, Rn; uint32_t register_list; @@ -1037,8 +1097,11 @@ static int evaluate_ldm_stm(uint32_t opcode, } } - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i%s, {%s}%s", - address, opcode, mnemonic, COND(opcode), addressing_mode, + snprintf(instruction->text, 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 + "\t%s%s%s r%i%s, {%s}%s", + address, opcode, + mnemonic, addressing_mode, COND(opcode), Rn, (W) ? "!" : "", reg_list, (S) ? "^" : ""); return ERROR_OK; @@ -1046,7 +1109,7 @@ static int evaluate_ldm_stm(uint32_t opcode, /* Multiplies, extra load/stores */ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { /* Multiply (accumulate) (long) and Swap/swap byte */ if ((opcode & 0x000000f0) == 0x00000090) @@ -1138,7 +1201,7 @@ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, } static int evaluate_mrs_msr(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { int R = (opcode & 0x00400000) >> 22; char *PSR = (R) ? "SPSR" : "CPSR"; @@ -1193,7 +1256,7 @@ static int evaluate_mrs_msr(uint32_t opcode, /* Miscellaneous instructions */ static int evaluate_misc_instr(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { /* MRS/MSR */ if ((opcode & 0x000000f0) == 0x00000000) @@ -1384,7 +1447,7 @@ static int evaluate_misc_instr(uint32_t opcode, } static int evaluate_data_proc(uint32_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t I, op, S, Rn, Rd; char *mnemonic = NULL; @@ -1591,10 +1654,11 @@ static int evaluate_data_proc(uint32_t opcode, return ERROR_OK; } -int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction) +int arm_evaluate_opcode(uint32_t opcode, uint32_t address, + struct arm_instruction *instruction) { /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(arm_instruction_t)); + memset(instruction, 0, sizeof(struct arm_instruction)); instruction->opcode = opcode; instruction->instruction_size = 4; @@ -1605,13 +1669,9 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in if ((opcode & 0x08000000) == 0x00000000) return evaluate_pld(opcode, address, instruction); - /* Undefined instruction */ + /* Undefined instruction (or ARMv6+ SRS/RFE) */ if ((opcode & 0x0e000000) == 0x08000000) - { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode); - return ERROR_OK; - } + return evaluate_srs(opcode, address, instruction); /* Branch and branch with link and change to Thumb */ if ((opcode & 0x0e000000) == 0x0a000000) @@ -1717,7 +1777,7 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in } /* catch opcodes with [27:25] = b110 */ - if ((opcode & 0x0e000000) == 0x0a000000) + if ((opcode & 0x0e000000) == 0x0c000000) { /* Coprocessor load/store and double register transfers */ return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction); @@ -1739,12 +1799,13 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in return evaluate_cdp_mcr_mrc(opcode, address, instruction); } - LOG_ERROR("should never reach this point"); + LOG_ERROR("ARM: should never reach this point (opcode=%08x)", + (unsigned) opcode); return -1; } static int evaluate_b_bl_blx_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = opcode & 0x7ff; uint32_t opc = (opcode >> 11) & 0x3; @@ -1784,8 +1845,12 @@ static int evaluate_b_bl_blx_thumb(uint16_t opcode, } /* TODO: deal correctly with dual opcode (prefixed) BL/BLX; - * these are effectively 32-bit instructions even in Thumb1. - * Might be simplest to always use the Thumb2 decoder. + * these are effectively 32-bit instructions even in Thumb1. For + * disassembly, it's simplest to always use the Thumb2 decoder. + * + * But some cores will evidently handle them as two instructions, + * where exceptions may occur between the two. The ETMv3.2+ ID + * register has a bit which exposes this behavior. */ snprintf(instruction->text, 128, @@ -1799,7 +1864,7 @@ static int evaluate_b_bl_blx_thumb(uint16_t opcode, } static int evaluate_add_sub_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t Rd = (opcode >> 0) & 0x7; uint8_t Rn = (opcode >> 3) & 0x7; @@ -1845,7 +1910,7 @@ static int evaluate_add_sub_thumb(uint16_t opcode, } static int evaluate_shift_imm_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t Rd = (opcode >> 0) & 0x7; uint8_t Rm = (opcode >> 3) & 0x7; @@ -1891,7 +1956,7 @@ static int evaluate_shift_imm_thumb(uint16_t opcode, } static int evaluate_data_proc_imm_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t imm = opcode & 0xff; uint8_t Rd = (opcode >> 8) & 0x7; @@ -1934,7 +1999,7 @@ static int evaluate_data_proc_imm_thumb(uint16_t opcode, } static int evaluate_data_proc_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t high_reg, op, Rm, Rd,H1,H2; char *mnemonic = NULL; @@ -2120,7 +2185,7 @@ static inline uint32_t thumb_alignpc4(uint32_t addr) } static int evaluate_load_literal_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t immediate; uint8_t Rd = (opcode >> 8) & 0x7; @@ -2145,7 +2210,7 @@ static int evaluate_load_literal_thumb(uint16_t opcode, } static int evaluate_load_store_reg_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t Rd = (opcode >> 0) & 0x7; uint8_t Rn = (opcode >> 3) & 0x7; @@ -2203,7 +2268,7 @@ static int evaluate_load_store_reg_thumb(uint16_t opcode, } static int evaluate_load_store_imm_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = (opcode >> 6) & 0x1f; uint8_t Rd = (opcode >> 0) & 0x7; @@ -2250,7 +2315,7 @@ static int evaluate_load_store_imm_thumb(uint16_t opcode, } static int evaluate_load_store_stack_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = opcode & 0xff; uint8_t Rd = (opcode >> 8) & 0x7; @@ -2282,13 +2347,13 @@ static int evaluate_load_store_stack_thumb(uint16_t opcode, } static int evaluate_add_sp_pc_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t imm = opcode & 0xff; uint8_t Rd = (opcode >> 8) & 0x7; uint8_t Rn; uint32_t SP = opcode & (1 << 11); - char *reg_name; + const char *reg_name; instruction->type = ARM_ADD; @@ -2316,7 +2381,7 @@ static int evaluate_add_sp_pc_thumb(uint16_t opcode, } static int evaluate_adjust_stack_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t imm = opcode & 0x7f; uint8_t opc = opcode & (1 << 7); @@ -2347,7 +2412,7 @@ static int evaluate_adjust_stack_thumb(uint16_t opcode, } static int evaluate_breakpoint_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t imm = opcode & 0xff; @@ -2361,7 +2426,7 @@ static int evaluate_breakpoint_thumb(uint16_t opcode, } static int evaluate_load_store_multiple_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t reg_list = opcode & 0xff; uint32_t L = opcode & (1 << 11); @@ -2439,7 +2504,7 @@ static int evaluate_load_store_multiple_thumb(uint16_t opcode, } static int evaluate_cond_branch_thumb(uint16_t opcode, - uint32_t address, arm_instruction_t *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = opcode & 0xff; uint8_t cond = (opcode >> 8) & 0xf; @@ -2481,7 +2546,7 @@ static int evaluate_cond_branch_thumb(uint16_t opcode, } static int evaluate_cb_thumb(uint16_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { unsigned offset; @@ -2499,7 +2564,7 @@ static int evaluate_cb_thumb(uint16_t opcode, uint32_t address, } static int evaluate_extend_thumb(uint16_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { /* added in ARMv6 */ snprintf(instruction->text, 128, @@ -2513,7 +2578,7 @@ static int evaluate_extend_thumb(uint16_t opcode, uint32_t address, } static int evaluate_cps_thumb(uint16_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { /* added in ARMv6 */ if ((opcode & 0x0ff0) == 0x0650) @@ -2534,7 +2599,7 @@ static int evaluate_cps_thumb(uint16_t opcode, uint32_t address, } static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { char *suffix; @@ -2559,7 +2624,7 @@ static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address, } static int evaluate_hint_thumb(uint16_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { char *hint; @@ -2592,7 +2657,7 @@ static int evaluate_hint_thumb(uint16_t opcode, uint32_t address, } static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address, - arm_instruction_t *instruction) + struct arm_instruction *instruction) { unsigned cond = (opcode >> 4) & 0x0f; char *x = "", *y = "", *z = ""; @@ -2616,10 +2681,10 @@ static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address, return ERROR_OK; } -int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) +int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction) { /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(arm_instruction_t)); + memset(instruction, 0, sizeof(struct arm_instruction)); instruction->opcode = opcode; instruction->instruction_size = 2; @@ -2749,12 +2814,12 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t * } } - LOG_ERROR("should never reach this point (opcode=%04x)",opcode); + LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode); return -1; } static int t2ev_b_bl(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned offset; unsigned b21 = 1 << 21; @@ -2795,7 +2860,7 @@ static int t2ev_b_bl(uint32_t opcode, uint32_t address, } static int t2ev_cond_b(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned offset; unsigned b17 = 1 << 17; @@ -2884,7 +2949,7 @@ static const char *special_name(int number) } static int t2ev_hint(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { const char *mnemonic; @@ -2924,7 +2989,7 @@ static int t2ev_hint(uint32_t opcode, uint32_t address, } static int t2ev_misc(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { const char *mnemonic; @@ -2955,7 +3020,7 @@ static int t2ev_misc(uint32_t opcode, uint32_t address, } static int t2ev_b_misc(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { /* permanently undefined */ if ((opcode & 0x07f07000) == 0x07f02000) { @@ -3003,7 +3068,7 @@ undef: } static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { char *mnemonic = NULL; int rn = (opcode >> 16) & 0xf; @@ -3149,7 +3214,7 @@ static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address, } static int t2ev_data_immed(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { char *mnemonic = NULL; int rn = (opcode >> 16) & 0xf; @@ -3182,7 +3247,7 @@ static int t2ev_data_immed(uint32_t opcode, uint32_t address, case 0x0c: /* move constant to top 16 bits of register */ immed |= (opcode >> 4) & 0xf000; - sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rn, immed, immed); + sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed); return ERROR_OK; case 0x10: case 0x12: @@ -3244,7 +3309,7 @@ do_adr: } static int t2ev_store_single(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned op = (opcode >> 20) & 0xf; char *size = ""; @@ -3337,7 +3402,7 @@ imm8: } static int t2ev_mul32(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int ra = (opcode >> 12) & 0xf; @@ -3367,7 +3432,7 @@ static int t2ev_mul32(uint32_t opcode, uint32_t address, } static int t2ev_mul64_div(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int op = (opcode >> 4) & 0xf; char *infix = "MUL"; @@ -3404,17 +3469,34 @@ static int t2ev_mul64_div(uint32_t opcode, uint32_t address, } static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int op = (opcode >> 22) & 0x6; int t = (opcode >> 21) & 1; unsigned registers = opcode & 0xffff; + char *mode = ""; if (opcode & (1 << 20)) op |= 1; switch (op) { + case 0: + mode = "DB"; + /* FALL THROUGH */ + case 6: + sprintf(cp, "SRS%s\tsp%s, #%d", mode, + t ? "!" : "", + (unsigned) (opcode & 0x1f)); + return ERROR_OK; + case 1: + mode = "DB"; + /* FALL THROUGH */ + case 7: + sprintf(cp, "RFE%s\tr%d%s", mode, + (unsigned) ((opcode >> 16) & 0xf), + t ? "!" : ""); + return ERROR_OK; case 2: sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : ""); break; @@ -3454,7 +3536,7 @@ static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, /* load/store dual or exclusive, table branch */ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned op1op2 = (opcode >> 20) & 0x3; unsigned op3 = (opcode >> 4) & 0xf; @@ -3580,7 +3662,7 @@ literal: } static int t2ev_data_shift(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int op = (opcode >> 21) & 0xf; int rd = (opcode >> 8) & 0xf; @@ -3755,7 +3837,7 @@ immediate: } static int t2ev_data_reg(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { char *mnemonic; char * suffix = ""; @@ -3856,7 +3938,7 @@ static int t2ev_data_reg(uint32_t opcode, uint32_t address, } static int t2ev_load_word(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int immed; @@ -3930,7 +4012,7 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address, } static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int rt = (opcode >> 12) & 0xf; @@ -4109,7 +4191,7 @@ ldrsb_literal: } static int t2ev_load_halfword(uint32_t opcode, uint32_t address, - arm_instruction_t *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int rt = (opcode >> 12) & 0xf; @@ -4191,7 +4273,7 @@ ldrh_literal: * always set. That means eventual arm_simulate_step() support for Thumb2 * will need work in this area. */ -int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruction) +int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction) { int retval; uint16_t op; @@ -4202,7 +4284,7 @@ int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruc address &= ~1; /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(arm_instruction_t)); + memset(instruction, 0, sizeof(struct arm_instruction)); /* read first halfword, see if this is the only one */ retval = target_read_u16(target, address, &op); @@ -4308,7 +4390,7 @@ int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruc return ERROR_OK; } -int arm_access_size(arm_instruction_t *instruction) +int arm_access_size(struct arm_instruction *instruction) { if ((instruction->type == ARM_LDRB) || (instruction->type == ARM_LDRBT)