X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm_disassembler.c;h=94479261da11de1d0820c5c008cb4e64e97b7669;hp=9ba2865736241ec0d07ca09a353ecb98a3b5e6c4;hb=2e779198535580515dfa9c8bfe1f3fe08abdb84b;hpb=c493543fc93cb693abab3146e08314b63d137470 diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 9ba2865736..94479261da 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -33,9 +33,9 @@ char *arm_condition_strings[] = }; /* make up for C's missing ROR */ -uint32_t ror(uint32_t value, int places) -{ - return (value >> places) | (value << (32 - places)); +uint32_t ror(uint32_t value, int places) +{ + return (value >> places) | (value << (32 - places)); } int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instruction) @@ -44,9 +44,9 @@ int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instructi if ((opcode & 0x0d70f0000) == 0x0550f000) { instruction->type = ARM_PLD; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode); - + return ERROR_OK; } else @@ -54,7 +54,7 @@ int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instructi instruction->type = ARM_UNDEFINED_INSTRUCTION; return ERROR_OK; } - + LOG_ERROR("should never reach this point"); return -1; } @@ -62,9 +62,9 @@ int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instructi int evaluate_swi(uint32_t opcode, uint32_t address, arm_instruction_t *instruction) { instruction->type = ARM_SWI; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI 0x%6.6" PRIx32 "", address, opcode, (opcode & 0xffffff)); - + return ERROR_OK; } @@ -73,30 +73,30 @@ int evaluate_blx_imm(uint32_t opcode, uint32_t address, arm_instruction_t *instr int offset; uint32_t immediate; uint32_t target_address; - + instruction->type = ARM_BLX; immediate = opcode & 0x00ffffff; - + /* sign extend 24-bit immediate */ if (immediate & 0x00800000) offset = 0xff000000 | immediate; else offset = immediate; - + /* shift two bits left */ offset <<= 2; - + /* odd/event halfword */ if (opcode & 0x01000000) offset |= 0x2; - + target_address = address + 8 + offset; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", address, opcode, target_address); - + instruction->info.b_bl_bx_blx.reg_operand = -1; instruction->info.b_bl_bx_blx.target_address = target_address; - + return ERROR_OK; } @@ -106,32 +106,32 @@ int evaluate_b_bl(uint32_t opcode, uint32_t address, arm_instruction_t *instruct uint32_t immediate; int offset; uint32_t target_address; - + immediate = opcode & 0x00ffffff; L = (opcode & 0x01000000) >> 24; - + /* sign extend 24-bit immediate */ if (immediate & 0x00800000) offset = 0xff000000 | immediate; else offset = immediate; - + /* shift two bits left */ offset <<= 2; - + target_address = address + 8 + offset; if (L) instruction->type = ARM_BL; else instruction->type = ARM_B; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32 , address, opcode, (L) ? "L" : "", COND(opcode), target_address); - + instruction->info.b_bl_bx_blx.reg_operand = -1; instruction->info.b_bl_bx_blx.target_address = target_address; - + return ERROR_OK; } @@ -140,32 +140,32 @@ int evaluate_b_bl(uint32_t opcode, uint32_t address, arm_instruction_t *instruct int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction) { uint8_t cp_num = (opcode & 0xf00) >> 8; - + /* MCRR or MRRC */ if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000)) { uint8_t cp_opcode, Rd, Rn, CRm; char *mnemonic; - + cp_opcode = (opcode & 0xf0) >> 4; Rd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; CRm = (opcode & 0xf); - + /* MCRR */ if ((opcode & 0x0ff00000) == 0x0c400000) { instruction->type = ARM_MCRR; mnemonic = "MCRR"; } - + /* MRRC */ if ((opcode & 0x0ff00000) == 0x0c500000) { instruction->type = ARM_MRRC; 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); } @@ -175,11 +175,11 @@ int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instructio uint8_t U, N; char *mnemonic; char addressing_mode[32]; - + CRd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; offset = (opcode & 0xff); - + /* load/store */ if (opcode & 0x00100000) { @@ -191,10 +191,10 @@ int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instructio instruction->type = ARM_STC; mnemonic = "STC"; } - + 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); @@ -210,7 +210,7 @@ int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instructio (N) ? "L" : "", cp_num, CRd, addressing_mode); } - + return ERROR_OK; } @@ -222,14 +222,14 @@ int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *i char* cond; char* mnemonic; uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2; - + cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode); cp_num = (opcode & 0xf00) >> 8; CRd_Rd = (opcode & 0xf000) >> 12; CRn = (opcode & 0xf0000) >> 16; CRm = (opcode & 0xf); opcode_2 = (opcode & 0xe0) >> 5; - + /* CDP or MRC/MCR */ if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */ { @@ -243,9 +243,9 @@ int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *i instruction->type = ARM_MCR; mnemonic = "MCR"; } - + opcode_1 = (opcode & 0x00e00000) >> 21; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x", address, opcode, mnemonic, cond, cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2); @@ -254,14 +254,14 @@ int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *i { instruction->type = ARM_CDP; mnemonic = "CDP"; - + opcode_1 = (opcode & 0x00f00000) >> 20; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x", address, opcode, mnemonic, cond, cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2); } - + return ERROR_OK; } @@ -273,7 +273,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in char *operation; /* "LDR" or "STR" */ char *suffix; /* "", "B", "T", "BT" */ char offset[32]; - + /* examine flags */ I = (opcode & 0x02000000) >> 25; P = (opcode & 0x01000000) >> 24; @@ -281,13 +281,13 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in B = (opcode & 0x00400000) >> 22; W = (opcode & 0x00200000) >> 21; L = (opcode & 0x00100000) >> 20; - + /* target register */ Rd = (opcode & 0xf000) >> 12; - + /* base register */ Rn = (opcode & 0xf0000) >> 16; - + instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = Rn; instruction->info.load_store.U = U; @@ -297,7 +297,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in operation = "LDR"; else operation = "STR"; - + /* determine instruction type and suffix */ if (B) { @@ -337,7 +337,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in suffix = ""; } } - + if (!I) /* #+- */ { uint32_t offset_12 = (opcode & 0xfff); @@ -345,7 +345,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12); else snprintf(offset, 32, "%s", ""); - + instruction->info.load_store.offset_mode = 0; instruction->info.load_store.offset.offset = offset_12; } @@ -353,15 +353,15 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in { uint8_t shift_imm, shift; uint8_t Rm; - + shift_imm = (opcode & 0xf80) >> 7; shift = (opcode & 0x60) >> 5; Rm = (opcode & 0xf); - + /* LSR encodes a shift by 32 bit as 0x0 */ if ((shift == 0x1) && (shift_imm == 0x0)) shift_imm = 0x20; - + /* ASR encodes a shift by 32 bit as 0x0 */ if ((shift == 0x2) && (shift_imm == 0x0)) shift_imm = 0x20; @@ -369,7 +369,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in /* ROR by 32 bit is actually a RRX */ if ((shift == 0x3) && (shift_imm == 0x0)) shift = 0x4; - + instruction->info.load_store.offset_mode = 1; instruction->info.load_store.offset.reg.Rm = Rm; instruction->info.load_store.offset.reg.shift = shift; @@ -401,7 +401,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in } } } - + if (P == 1) { if (W == 0) /* offset */ @@ -409,7 +409,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]", address, opcode, operation, COND(opcode), suffix, Rd, Rn, offset); - + instruction->info.load_store.index_mode = 0; } else /* pre-indexed */ @@ -417,7 +417,7 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!", address, opcode, operation, COND(opcode), suffix, Rd, Rn, offset); - + instruction->info.load_store.index_mode = 1; } } @@ -426,10 +426,10 @@ int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s", address, opcode, operation, COND(opcode), suffix, Rd, Rn, offset); - + instruction->info.load_store.index_mode = 2; } - + return ERROR_OK; } @@ -441,7 +441,7 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ char *operation; /* "LDR" or "STR" */ char *suffix; /* "H", "SB", "SH", "D" */ char offset[32]; - + /* examine flags */ P = (opcode & 0x01000000) >> 24; U = (opcode & 0x00800000) >> 23; @@ -450,17 +450,17 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ L = (opcode & 0x00100000) >> 20; S = (opcode & 0x00000040) >> 6; H = (opcode & 0x00000020) >> 5; - + /* target register */ Rd = (opcode & 0xf000) >> 12; - + /* base register */ Rn = (opcode & 0xf0000) >> 16; - + instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = Rn; instruction->info.load_store.U = U; - + /* determine instruction type and suffix */ if (S) /* signed */ { @@ -508,12 +508,12 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ instruction->type = ARM_STRH; } } - + if (I) /* Immediate offset/index (#+-)*/ { uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf); snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8); - + instruction->info.load_store.offset_mode = 0; instruction->info.load_store.offset.offset = offset_8; } @@ -522,13 +522,13 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ uint8_t Rm; Rm = (opcode & 0xf); snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm); - + instruction->info.load_store.offset_mode = 1; instruction->info.load_store.offset.reg.Rm = Rm; instruction->info.load_store.offset.reg.shift = 0x0; instruction->info.load_store.offset.reg.shift_imm = 0x0; } - + if (P == 1) { if (W == 0) /* offset */ @@ -536,7 +536,7 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]", address, opcode, operation, COND(opcode), suffix, Rd, Rn, offset); - + instruction->info.load_store.index_mode = 0; } else /* pre-indexed */ @@ -544,7 +544,7 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!", address, opcode, operation, COND(opcode), suffix, Rd, Rn, offset); - + instruction->info.load_store.index_mode = 1; } } @@ -553,10 +553,10 @@ int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_ snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s", address, opcode, operation, COND(opcode), suffix, Rd, Rn, offset); - + instruction->info.load_store.index_mode = 2; } - + return ERROR_OK; } @@ -571,7 +571,7 @@ int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instr char *reg_list_p; int i; int first_reg = 1; - + P = (opcode & 0x01000000) >> 24; U = (opcode & 0x00800000) >> 23; S = (opcode & 0x00400000) >> 22; @@ -579,12 +579,12 @@ int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instr L = (opcode & 0x00100000) >> 20; register_list = (opcode & 0xffff); Rn = (opcode & 0xf0000) >> 16; - + instruction->info.load_store_multiple.Rn = Rn; instruction->info.load_store_multiple.register_list = register_list; instruction->info.load_store_multiple.S = S; instruction->info.load_store_multiple.W = W; - + if (L) { instruction->type = ARM_LDM; @@ -595,7 +595,7 @@ int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instr instruction->type = ARM_STM; mnemonic = "STM"; } - + if (P) { if (U) @@ -622,7 +622,7 @@ int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instr addressing_mode = "DA"; } } - + reg_list_p = reg_list; for (i = 0; i <= 15; i++) { @@ -639,11 +639,11 @@ int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instr } } } - + 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, Rn, (W) ? "!" : "", reg_list, (S) ? "^" : ""); - + return ERROR_OK; } @@ -662,7 +662,7 @@ int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruct Rn = (opcode & 0xf000) >> 12; Rd = (opcode & 0xf0000) >> 16; S = (opcode & 0x00100000) >> 20; - + /* examine A bit (accumulate) */ if (opcode & 0x00200000) { @@ -676,10 +676,10 @@ int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruct snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i", address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs); } - + return ERROR_OK; } - + /* Multiply (accumulate) long */ if ((opcode & 0x0f800000) == 0x00800000) { @@ -690,7 +690,7 @@ int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruct RdHi = (opcode & 0xf000) >> 12; RdLow = (opcode & 0xf0000) >> 16; S = (opcode & 0x00100000) >> 20; - + switch ((opcode & 0x00600000) >> 21) { case 0x0: @@ -710,14 +710,14 @@ int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruct mnemonic = "SMLAL"; break; } - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i", address, opcode, mnemonic, COND(opcode), (S) ? "S" : "", RdLow, RdHi, Rm, Rs); - + return ERROR_OK; } - + /* Swap/swap byte */ if ((opcode & 0x0f800000) == 0x01000000) { @@ -725,17 +725,17 @@ int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruct Rm = opcode & 0xf; Rd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; - + /* examine B flag */ instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]", address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn); return ERROR_OK; } - + } - + return evaluate_misc_load_store(opcode, address, instruction); } @@ -743,18 +743,18 @@ int evaluate_mrs_msr(uint32_t opcode, uint32_t address, arm_instruction_t *instr { int R = (opcode & 0x00400000) >> 22; char *PSR = (R) ? "SPSR" : "CPSR"; - + /* Move register to status register (MSR) */ if (opcode & 0x00200000) { instruction->type = ARM_MSR; - + /* immediate variant */ if (opcode & 0x02000000) { uint8_t immediate = (opcode & 0xff); uint8_t rotate = (opcode & 0xf00); - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 , address, opcode, COND(opcode), PSR, (opcode & 0x10000) ? "c" : "", @@ -776,19 +776,19 @@ int evaluate_mrs_msr(uint32_t opcode, uint32_t address, arm_instruction_t *instr Rm ); } - + } else /* Move status register to register (MRS) */ { uint8_t Rd; - + instruction->type = ARM_MRS; Rd = (opcode & 0x0000f000) >> 12; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s", address, opcode, COND(opcode), Rd, PSR); } - + return ERROR_OK; } @@ -800,21 +800,21 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in { evaluate_mrs_msr(opcode, address, instruction); } - + /* BX */ if ((opcode & 0x006000f0) == 0x00200010) { uint8_t Rm; instruction->type = ARM_BX; Rm = opcode & 0xf; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i", address, opcode, COND(opcode), Rm); - + instruction->info.b_bl_bx_blx.reg_operand = Rm; instruction->info.b_bl_bx_blx.target_address = -1; } - + /* CLZ */ if ((opcode & 0x006000f0) == 0x00600010) { @@ -826,21 +826,21 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i", address, opcode, COND(opcode), Rd, Rm); } - + /* BLX(2) */ if ((opcode & 0x006000f0) == 0x00200030) { uint8_t Rm; instruction->type = ARM_BLX; Rm = opcode & 0xf; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i", address, opcode, COND(opcode), Rm); - + instruction->info.b_bl_bx_blx.reg_operand = Rm; instruction->info.b_bl_bx_blx.target_address = -1; } - + /* Enhanced DSP add/subtracts */ if ((opcode & 0x0000000f0) == 0x00000050) { @@ -849,7 +849,7 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in Rm = opcode & 0xf; Rd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; - + switch ((opcode & 0x00600000) >> 21) { case 0x0: @@ -869,28 +869,28 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in mnemonic = "QDSUB"; break; } - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i", address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn); } - + /* Software breakpoints */ if ((opcode & 0x0000000f0) == 0x00000070) { uint32_t immediate; instruction->type = ARM_BKPT; immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf); - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "", - address, opcode, immediate); + address, opcode, immediate); } - + /* Enhanced DSP multiplies */ if ((opcode & 0x000000090) == 0x00000080) { int x = (opcode & 0x20) >> 5; int y = (opcode & 0x40) >> 6; - + /* SMLA < x> */ if ((opcode & 0x00600000) == 0x00000000) { @@ -900,12 +900,12 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in Rm = (opcode & 0xf); Rs = (opcode & 0xf00) >> 8; Rn = (opcode & 0xf000) >> 12; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i", address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode), Rd, Rm, Rs, Rn); } - + /* SMLAL < x> */ if ((opcode & 0x00600000) == 0x00400000) { @@ -915,12 +915,12 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in RdLow = (opcode & 0xf000) >> 12; Rm = (opcode & 0xf); Rs = (opcode & 0xf00) >> 8; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i", address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode), RdLow, RdHi, Rm, Rs); } - + /* SMLAW < y> */ if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) { @@ -935,7 +935,7 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in address, opcode, (y) ? "T" : "B", COND(opcode), Rd, Rm, Rs, Rn); } - + /* SMUL < x> */ if ((opcode & 0x00600000) == 0x00300000) { @@ -944,12 +944,12 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in Rd = (opcode & 0xf0000) >> 16; Rm = (opcode & 0xf); Rs = (opcode & 0xf00) >> 8; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i", address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode), Rd, Rm, Rs); } - + /* SMULW < y> */ if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) { @@ -958,13 +958,13 @@ int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *in Rd = (opcode & 0xf0000) >> 16; Rm = (opcode & 0xf); Rs = (opcode & 0xf00) >> 8; - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i", address, opcode, (y) ? "T" : "B", COND(opcode), Rd, Rm, Rs); } } - + return ERROR_OK; } @@ -973,14 +973,14 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins uint8_t I, op, S, Rn, Rd; char *mnemonic = NULL; char shifter_operand[32]; - + I = (opcode & 0x02000000) >> 25; op = (opcode & 0x01e00000) >> 21; S = (opcode & 0x00100000) >> 20; - + Rd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; - + instruction->info.data_proc.Rd = Rd; instruction->info.data_proc.Rn = Rn; instruction->info.data_proc.S = S; @@ -1052,17 +1052,17 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins mnemonic = "MVN"; break; } - + if (I) /* immediate shifter operand (#)*/ { uint8_t immed_8 = opcode & 0xff; uint8_t rotate_imm = (opcode & 0xf00) >> 8; uint32_t immediate; - + immediate = ror(immed_8, rotate_imm * 2); - + snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate); - + instruction->info.data_proc.variant = 0; instruction->info.data_proc.shifter_operand.immediate.immediate = immediate; } @@ -1071,7 +1071,7 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins uint8_t shift, Rm; shift = (opcode & 0x60) >> 5; Rm = (opcode & 0xf); - + if ((opcode & 0x10) != 0x10) /* Immediate shifts ("" or ", #") */ { uint8_t shift_imm; @@ -1081,11 +1081,11 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm; instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm; instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift; - + /* LSR encodes a shift by 32 bit as 0x0 */ if ((shift == 0x1) && (shift_imm == 0x0)) shift_imm = 0x20; - + /* ASR encodes a shift by 32 bit as 0x0 */ if ((shift == 0x2) && (shift_imm == 0x0)) shift_imm = 0x20; @@ -1093,7 +1093,7 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins /* ROR by 32 bit is actually a RRX */ if ((shift == 0x3) && (shift_imm == 0x0)) shift = 0x4; - + if ((shift_imm == 0x0) && (shift == 0x0)) { snprintf(shifter_operand, 32, "r%i", Rm); @@ -1125,12 +1125,12 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins else /* Register shifts (", ") */ { uint8_t Rs = (opcode & 0xf00) >> 8; - + instruction->info.data_proc.variant = 2; instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm; instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs; instruction->info.data_proc.shifter_operand.register_shift.shift = shift; - + if (shift == 0x0) /* LSL */ { snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs); @@ -1149,7 +1149,7 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins } } } - + if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* {}{S} , , */ { snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s", @@ -1171,23 +1171,23 @@ int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *ins address, opcode, mnemonic, COND(opcode), Rn, shifter_operand); } - + return ERROR_OK; } - + int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction) { /* clear fields, to avoid confusion */ memset(instruction, 0, sizeof(arm_instruction_t)); instruction->opcode = opcode; - + /* catch opcodes with condition field [31:28] = b1111 */ if ((opcode & 0xf0000000) == 0xf0000000) { /* Undefined instruction (or ARMv5E cache preload PLD) */ if ((opcode & 0x08000000) == 0x00000000) return evaluate_pld(opcode, address, instruction); - + /* Undefined instruction */ if ((opcode & 0x0e000000) == 0x08000000) { @@ -1195,24 +1195,24 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode); return ERROR_OK; } - + /* Branch and branch with link and change to Thumb */ if ((opcode & 0x0e000000) == 0x0a000000) return evaluate_blx_imm(opcode, address, instruction); - + /* Extended coprocessor opcode space (ARMv5 and higher)*/ /* Coprocessor load/store and double register transfers */ if ((opcode & 0x0e000000) == 0x0c000000) return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction); - + /* Coprocessor data processing */ if ((opcode & 0x0f000100) == 0x0c000000) return evaluate_cdp_mcr_mrc(opcode, address, instruction); - + /* Coprocessor register transfers */ if ((opcode & 0x0f000010) == 0x0c000010) return evaluate_cdp_mcr_mrc(opcode, address, instruction); - + /* Undefined instruction */ if ((opcode & 0x0f000000) == 0x0f000000) { @@ -1221,21 +1221,21 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in return ERROR_OK; } } - + /* catch opcodes with [27:25] = b000 */ if ((opcode & 0x0e000000) == 0x00000000) { /* Multiplies, extra load/stores */ if ((opcode & 0x00000090) == 0x00000090) return evaluate_mul_and_extra_ld_st(opcode, address, instruction); - + /* Miscellaneous instructions */ if ((opcode & 0x0f900000) == 0x01000000) return evaluate_misc_instr(opcode, address, instruction); - + return evaluate_data_proc(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b001 */ if ((opcode & 0x0e000000) == 0x02000000) { @@ -1246,22 +1246,22 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode); return ERROR_OK; } - + /* Move immediate to status register */ if ((opcode & 0x0fb00000) == 0x03200000) return evaluate_mrs_msr(opcode, address, instruction); - + return evaluate_data_proc(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b010 */ if ((opcode & 0x0e000000) == 0x04000000) { /* Load/store immediate offset */ return evaluate_load_store(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b011 */ if ((opcode & 0x0e000000) == 0x06000000) { @@ -1272,49 +1272,49 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *in snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode); return ERROR_OK; } - + /* Load/store register offset */ return evaluate_load_store(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b100 */ if ((opcode & 0x0e000000) == 0x08000000) { /* Load/store multiple */ return evaluate_ldm_stm(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b101 */ if ((opcode & 0x0e000000) == 0x0a000000) { /* Branch and branch with link */ return evaluate_b_bl(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b110 */ if ((opcode & 0x0e000000) == 0x0a000000) { /* Coprocessor load/store and double register transfers */ return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction); } - + /* catch opcodes with [27:25] = b111 */ if ((opcode & 0x0e000000) == 0x0e000000) { /* Software interrupt */ if ((opcode & 0x0f000000) == 0x0f000000) return evaluate_swi(opcode, address, instruction); - + /* Coprocessor data processing */ if ((opcode & 0x0f000010) == 0x0e000000) return evaluate_cdp_mcr_mrc(opcode, address, instruction); - + /* Coprocessor register transfers */ if ((opcode & 0x0f000010) == 0x0e000010) return evaluate_cdp_mcr_mrc(opcode, address, instruction); } - + LOG_ERROR("should never reach this point"); return -1; } @@ -1325,11 +1325,11 @@ int evaluate_b_bl_blx_thumb(uint16_t opcode, uint32_t address, arm_instruction_t uint32_t opc = (opcode >> 11) & 0x3; uint32_t target_address; char *mnemonic = NULL; - + /* sign extend 11-bit offset */ if (((opc == 0) || (opc == 2)) && (offset & 0x00000400)) offset = 0xfffff800 | offset; - + target_address = address + 4 + (offset << 1); switch (opc) @@ -1359,7 +1359,7 @@ int evaluate_b_bl_blx_thumb(uint16_t opcode, uint32_t address, arm_instruction_t /* TODO: deals correctly with dual opcodes BL/BLX ... */ snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s 0x%8.8" PRIx32 , address, opcode,mnemonic, target_address); - + instruction->info.b_bl_bx_blx.reg_operand = -1; instruction->info.b_bl_bx_blx.target_address = target_address; @@ -1374,7 +1374,7 @@ int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t uint32_t opc = opcode & (1 << 9); uint32_t reg_imm = opcode & (1 << 10); char *mnemonic; - + if (opc) { instruction->type = ARM_SUB; @@ -1385,7 +1385,7 @@ int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t instruction->type = ARM_ADD; mnemonic = "ADDS"; } - + instruction->info.data_proc.Rd = Rd; instruction->info.data_proc.Rn = Rn; instruction->info.data_proc.S = 1; @@ -1415,7 +1415,7 @@ int evaluate_shift_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_ uint8_t imm = (opcode >> 6) & 0x1f; uint8_t opc = (opcode >> 11) & 0x3; char *mnemonic = NULL; - + switch (opc) { case 0: @@ -1458,13 +1458,13 @@ int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruct uint8_t Rd = (opcode >> 8) & 0x7; uint32_t opc = (opcode >> 11) & 0x3; char *mnemonic = NULL; - + instruction->info.data_proc.Rd = Rd; instruction->info.data_proc.Rn = Rd; instruction->info.data_proc.S = 1; instruction->info.data_proc.variant = 0; /*immediate*/ instruction->info.data_proc.shifter_operand.immediate.immediate = imm; - + switch (opc) { case 0: @@ -1486,7 +1486,7 @@ int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruct mnemonic = "SUBS"; break; } - + snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, #0x%02x" , address, opcode, mnemonic, Rd, imm); @@ -1497,15 +1497,15 @@ int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_ { uint8_t high_reg, op, Rm, Rd,H1,H2; char *mnemonic = NULL; - + high_reg = (opcode & 0x0400) >> 10; op = (opcode & 0x03C0) >> 6; - + Rd = (opcode & 0x0007); Rm = (opcode & 0x0038) >> 3; H1 = (opcode & 0x0080) >> 7; H2 = (opcode & 0x0040) >> 6; - + instruction->info.data_proc.Rd = Rd; instruction->info.data_proc.Rn = Rd; instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP)); @@ -1517,7 +1517,7 @@ int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_ Rd |= H1 << 3; Rm |= H2 << 3; op >>= 2; - + switch (op) { case 0x0: @@ -1552,7 +1552,7 @@ int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_ instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode); } - return ERROR_OK; + return ERROR_OK; break; } } @@ -1655,7 +1655,7 @@ int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_ int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) { uint32_t immediate; - uint8_t Rd = (opcode >> 8) & 0x7; + uint8_t Rd = (opcode >> 8) & 0x7; instruction->type = ARM_LDR; immediate = opcode & 0x000000ff; @@ -1673,10 +1673,10 @@ int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instructi int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) { - uint8_t Rd = (opcode >> 0) & 0x7; - uint8_t Rn = (opcode >> 3) & 0x7; - uint8_t Rm = (opcode >> 6) & 0x7; - uint8_t opc = (opcode >> 9) & 0x7; + uint8_t Rd = (opcode >> 0) & 0x7; + uint8_t Rn = (opcode >> 3) & 0x7; + uint8_t Rm = (opcode >> 6) & 0x7; + uint8_t opc = (opcode >> 9) & 0x7; char *mnemonic = NULL; switch (opc) @@ -1716,7 +1716,7 @@ int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruc } snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [r%i, r%i]", address, opcode, mnemonic, Rd, Rn, Rm); - + instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = Rn; instruction->info.load_store.index_mode = 0; /*offset*/ @@ -1729,8 +1729,8 @@ int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruc int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) { uint32_t offset = (opcode >> 6) & 0x1f; - uint8_t Rd = (opcode >> 0) & 0x7; - uint8_t Rn = (opcode >> 3) & 0x7; + uint8_t Rd = (opcode >> 0) & 0x7; + uint8_t Rn = (opcode >> 3) & 0x7; uint32_t L = opcode & (1 << 11); uint32_t B = opcode & (1 << 12); char *mnemonic; @@ -1760,7 +1760,7 @@ int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruc } snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s%c r%i, [r%i, #0x%" PRIx32 "]", address, opcode, mnemonic, suffix, Rd, Rn, offset << shift); - + instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = Rn; instruction->info.load_store.index_mode = 0; /*offset*/ @@ -1773,7 +1773,7 @@ int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruc int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) { uint32_t offset = opcode & 0xff; - uint8_t Rd = (opcode >> 8) & 0x7; + uint8_t Rd = (opcode >> 8) & 0x7; uint32_t L = opcode & (1 << 11); char *mnemonic; @@ -1789,7 +1789,7 @@ int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instr } snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [SP, #0x%" PRIx32 "]", address, opcode, mnemonic, Rd, offset*4); - + instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = 13 /*SP*/; instruction->info.load_store.index_mode = 0; /*offset*/ @@ -1802,13 +1802,13 @@ int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instr int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) { uint32_t imm = opcode & 0xff; - uint8_t Rd = (opcode >> 8) & 0x7; + uint8_t Rd = (opcode >> 8) & 0x7; uint8_t Rn; uint32_t SP = opcode & (1 << 11); char *reg_name; instruction->type = ARM_ADD; - + if (SP) { reg_name = "SP"; @@ -1836,7 +1836,7 @@ int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instructi uint8_t opc = opcode & (1 << 7); char *mnemonic; - + if (opc) { instruction->type = ARM_SUB; @@ -1861,7 +1861,7 @@ int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instructi int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction) { uint32_t imm = opcode & 0xff; - + instruction->type = ARM_BKPT; snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBKPT 0x%02" PRIx32 "", address, opcode, imm); @@ -1880,7 +1880,7 @@ int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_in char *reg_names_p; char *mnemonic; char ptr_name[7] = ""; - int i; + int i; if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */ @@ -1958,12 +1958,12 @@ int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instructio /* sign extend 8-bit offset */ if (offset & 0x00000080) offset = 0xffffff00 | offset; - + target_address = address + 4 + (offset << 1); snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tB%s 0x%8.8" PRIx32 , address, opcode, arm_condition_strings[cond], target_address); - + instruction->type = ARM_B; instruction->info.b_bl_bx_blx.reg_operand = -1; instruction->info.b_bl_bx_blx.target_address = target_address; @@ -1976,7 +1976,7 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t * /* clear fields, to avoid confusion */ memset(instruction, 0, sizeof(arm_instruction_t)); instruction->opcode = opcode; - + if ((opcode & 0xe000) == 0x0000) { /* add/substract register or immediate */ @@ -1986,19 +1986,19 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t * else return evaluate_shift_imm_thumb(opcode, address, instruction); } - + /* Add/substract/compare/move immediate */ if ((opcode & 0xe000) == 0x2000) { return evaluate_data_proc_imm_thumb(opcode, address, instruction); } - + /* Data processing instructions */ if ((opcode & 0xf800) == 0x4000) { return evaluate_data_proc_thumb(opcode, address, instruction); } - + /* Load from literal pool */ if ((opcode & 0xf800) == 0x4800) { @@ -2017,7 +2017,7 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t * { return evaluate_load_store_imm_thumb(opcode, address, instruction); } - + /* Load/Store from/to stack */ if ((opcode & 0xf000) == 0x9000) { @@ -2058,7 +2058,7 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t * { return evaluate_cond_branch_thumb(opcode, address, instruction); } - + if ((opcode & 0xe000) == 0xe000) { /* Undefined instructions */