X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm_disassembler.c;h=f11a5221a15968d0619f955fe1b7c7c0941d0c0a;hp=34d679c113b7a33355842294e914653501383725;hb=374127301ec1d72033b9d573b72c7abdfd61990d;hpb=de0130a0aad83c1ef692ee4d68ab996a8668424d diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 34d679c113..f11a5221a1 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -19,6 +19,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -27,7 +28,6 @@ #include "arm_disassembler.h" #include - /* * This disassembler supports two main functions for OpenOCD: * @@ -94,10 +94,9 @@ * the Cortex-M implementations). */ -/* textual represenation of the condition field */ -/* ALways (default) is ommitted (empty string) */ -static const char *arm_condition_strings[] = -{ +/* textual represenation of the condition field + * ALways (default) is ommitted (empty string) */ +static const char *arm_condition_strings[] = { "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV" }; @@ -108,7 +107,7 @@ static uint32_t ror(uint32_t value, int places) } static int evaluate_unknown(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, @@ -118,14 +117,17 @@ static int evaluate_unknown(uint32_t opcode, } static int evaluate_pld(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { /* PLD */ - if ((opcode & 0x0d70f000) == 0x0550f000) - { + if ((opcode & 0x0d70f000) == 0x0550f000) { instruction->type = ARM_PLD; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode); + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", + address, + opcode); return ERROR_OK; } @@ -133,51 +135,51 @@ static int evaluate_pld(uint32_t opcode, } static int evaluate_srs(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + 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; + case 0: + mode = "DA"; + break; + case 1: + /* "IA" is default */ + break; + case 2: + mode = "DB"; + break; + case 3: + mode = "IB"; + break; } switch (opcode & 0x0e500000) { - case 0x08400000: - snprintf(instruction->text, 128, "0x%8.8" PRIx32 + 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 + 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); + break; + default: + return evaluate_unknown(opcode, address, instruction); } return ERROR_OK; } static int evaluate_swi(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { instruction->type = ARM_SWI; @@ -189,7 +191,7 @@ static int evaluate_swi(uint32_t opcode, } static int evaluate_blx_imm(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { int offset; uint32_t immediate; @@ -213,7 +215,12 @@ static int evaluate_blx_imm(uint32_t opcode, 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); + 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; @@ -222,7 +229,7 @@ static int evaluate_blx_imm(uint32_t opcode, } static int evaluate_b_bl(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t L; uint32_t immediate; @@ -248,8 +255,14 @@ static int evaluate_b_bl(uint32_t opcode, 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); + 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; @@ -257,16 +270,15 @@ static int evaluate_b_bl(uint32_t opcode, return ERROR_OK; } -/* Coprocessor load/store and double register transfers */ -/* both normal and extended instruction space (condition field b1111) */ +/* 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, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t cp_num = (opcode & 0xf00) >> 8; /* MCRR or MRRC */ - if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000)) - { + if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000)) { uint8_t cp_opcode, Rd, Rn, CRm; char *mnemonic; @@ -276,8 +288,7 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, CRm = (opcode & 0xf); /* MCRR */ - if ((opcode & 0x0ff00000) == 0x0c400000) - { + if ((opcode & 0x0ff00000) == 0x0c400000) { instruction->type = ARM_MCRR; mnemonic = "MCRR"; } else if ((opcode & 0x0ff00000) == 0x0c500000) { @@ -292,13 +303,11 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, 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, + address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) - ? "2" : COND(opcode), - COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm); - } - else /* LDC or STC */ - { + ? "2" : COND(opcode), + COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm); + } else {/* LDC or STC */ uint8_t CRd, Rn, offset; uint8_t U; char *mnemonic; @@ -309,13 +318,10 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, offset = (opcode & 0xff) << 2; /* load/store */ - if (opcode & 0x00100000) - { + if (opcode & 0x00100000) { instruction->type = ARM_LDC; mnemonic = "LDC"; - } - else - { + } else { instruction->type = ARM_STC; mnemonic = "STC"; } @@ -323,16 +329,16 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, U = (opcode & 0x00800000) >> 23; /* addressing modes */ - if ((opcode & 0x01200000) == 0x01000000) /* offset */ + if ((opcode & 0x01200000) == 0x01000000)/* offset */ snprintf(addressing_mode, 32, "[r%i, #%s%d]", Rn, U ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */ + 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 */ + else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */ snprintf(addressing_mode, 32, "[r%i], #%s%d", Rn, U ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */ + else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */ snprintf(addressing_mode, 32, "[r%i], {%d}", Rn, offset >> 2); @@ -341,7 +347,7 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, "\t%s%s%s p%i, c%i, %s", address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) - ? "2" : COND(opcode), + ? "2" : COND(opcode), (opcode & (1 << 22)) ? "L" : "", cp_num, CRd, addressing_mode); } @@ -349,14 +355,14 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, return ERROR_OK; } -/* Coprocessor data processing instructions */ -/* Coprocessor register transfer instructions */ -/* both normal and extended instruction space (condition field b1111) */ +/* Coprocessor data processing instructions + * 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, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { const char *cond; - char* mnemonic; + char *mnemonic; uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2; cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode); @@ -367,35 +373,49 @@ static int evaluate_cdp_mcr_mrc(uint32_t opcode, opcode_2 = (opcode & 0xe0) >> 5; /* CDP or MRC/MCR */ - if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */ - { - if (opcode & 0x00100000) /* bit 20 set -> MRC */ - { + if (opcode & 0x00000010) { /* bit 4 set -> MRC/MCR */ + if (opcode & 0x00100000) { /* bit 20 set -> MRC */ instruction->type = ARM_MRC; mnemonic = "MRC"; - } - else /* bit 20 not set -> MCR */ - { + } else {/* bit 20 not set -> MCR */ 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); - } - else /* bit 4 not set -> CDP */ - { + 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); + } else {/* bit 4 not set -> CDP */ 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); + 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; @@ -403,12 +423,12 @@ static int evaluate_cdp_mcr_mrc(uint32_t opcode, /* Load/store instructions */ static int evaluate_load_store(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t I, P, U, B, W, L; uint8_t Rn, Rd; - char *operation; /* "LDR" or "STR" */ - char *suffix; /* "", "B", "T", "BT" */ + char *operation;/* "LDR" or "STR" */ + char *suffix; /* "", "B", "T", "BT" */ char offset[32]; /* examine flags */ @@ -436,37 +456,28 @@ static int evaluate_load_store(uint32_t opcode, operation = "STR"; /* determine instruction type and suffix */ - if (B) - { - if ((P == 0) && (W == 1)) - { + if (B) { + if ((P == 0) && (W == 1)) { if (L) instruction->type = ARM_LDRBT; else instruction->type = ARM_STRBT; suffix = "BT"; - } - else - { + } else { if (L) instruction->type = ARM_LDRB; else instruction->type = ARM_STRB; suffix = "B"; } - } - else - { - if ((P == 0) && (W == 1)) - { + } else { + if ((P == 0) && (W == 1)) { if (L) instruction->type = ARM_LDRT; else instruction->type = ARM_STRT; suffix = "T"; - } - else - { + } else { if (L) instruction->type = ARM_LDR; else @@ -475,8 +486,7 @@ static int evaluate_load_store(uint32_t opcode, } } - if (!I) /* #+- */ - { + if (!I) { /* #+- */ uint32_t offset_12 = (opcode & 0xfff); if (offset_12) snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12); @@ -485,9 +495,7 @@ static int evaluate_load_store(uint32_t opcode, instruction->info.load_store.offset_mode = 0; instruction->info.load_store.offset.offset = offset_12; - } - else /* either +- or +-, , # */ - { + } else {/* either +- or +-, , # */ uint8_t shift_imm, shift; uint8_t Rm; @@ -512,57 +520,71 @@ static int evaluate_load_store(uint32_t opcode, instruction->info.load_store.offset.reg.shift = shift; instruction->info.load_store.offset.reg.shift_imm = shift_imm; - if ((shift_imm == 0x0) && (shift == 0x0)) /* +- */ - { + if ((shift_imm == 0x0) && (shift == 0x0)) /* +- */ snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm); - } - else /* +-, , # */ - { - switch (shift) - { - case 0x0: /* LSL */ + else { /* +-, , # */ + switch (shift) { + case 0x0: /* LSL */ snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm); break; - case 0x1: /* LSR */ + case 0x1: /* LSR */ snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm); break; - case 0x2: /* ASR */ + case 0x2: /* ASR */ snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm); break; - case 0x3: /* ROR */ + case 0x3: /* ROR */ snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm); break; - case 0x4: /* RRX */ + case 0x4: /* RRX */ snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm); break; } } } - if (P == 1) - { - if (W == 0) /* offset */ - { - 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); + if (P == 1) { + if (W == 0) { /* offset */ + 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 */ - { - 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); + } else {/* pre-indexed */ + 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; } - } - else /* post-indexed */ - { - 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); + } else {/* post-indexed */ + 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; } @@ -578,33 +600,33 @@ static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp) char *type, *rot; switch ((opcode >> 24) & 0x3) { - case 0: - type = "B16"; - break; - case 1: - sprintf(cp, "UNDEFINED"); - return ARM_UNDEFINED_INSTRUCTION; - case 2: - type = "B"; - break; - default: - type = "H"; - break; + case 0: + type = "B16"; + break; + case 1: + sprintf(cp, "UNDEFINED"); + return ARM_UNDEFINED_INSTRUCTION; + case 2: + type = "B"; + break; + default: + type = "H"; + break; } switch ((opcode >> 10) & 0x3) { - case 0: - rot = ""; - break; - case 1: - rot = ", ROR #8"; - break; - case 2: - rot = ", ROR #16"; - break; - default: - rot = ", ROR #24"; - break; + case 0: + rot = ""; + break; + case 1: + rot = ", ROR #8"; + break; + case 2: + rot = ", ROR #16"; + break; + default: + rot = ", ROR #24"; + break; } if (rn == 0xf) { @@ -629,55 +651,55 @@ static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp) int type; switch ((opcode >> 20) & 0x7) { - case 1: - prefix = "S"; - break; - case 2: - prefix = "Q"; - break; - case 3: - prefix = "SH"; - break; - case 5: - prefix = "U"; - break; - case 6: - prefix = "UQ"; - break; - case 7: - prefix = "UH"; - break; - default: - goto undef; + case 1: + prefix = "S"; + break; + case 2: + prefix = "Q"; + break; + case 3: + prefix = "SH"; + break; + case 5: + prefix = "U"; + break; + case 6: + prefix = "UQ"; + break; + case 7: + prefix = "UH"; + break; + default: + goto undef; } switch ((opcode >> 5) & 0x7) { - case 0: - op = "ADD16"; - type = ARM_ADD; - break; - case 1: - op = "ADDSUBX"; - type = ARM_ADD; - break; - case 2: - op = "SUBADDX"; - type = ARM_SUB; - break; - case 3: - op = "SUB16"; - type = ARM_SUB; - break; - case 4: - op = "ADD8"; - type = ARM_ADD; - break; - case 7: - op = "SUB8"; - type = ARM_SUB; - break; - default: - goto undef; + case 0: + op = "ADD16"; + type = ARM_ADD; + break; + case 1: + op = "ADDSUBX"; + type = ARM_ADD; + break; + case 2: + op = "SUBADDX"; + type = ARM_SUB; + break; + case 3: + op = "SUB16"; + type = ARM_SUB; + break; + case 4: + op = "ADD8"; + type = ARM_ADD; + break; + case 7: + op = "SUB8"; + type = ARM_SUB; + break; + default: + goto undef; } sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode), @@ -694,14 +716,14 @@ undef: /* ARMv6 and later support "media" instructions (includes SIMD) */ static int evaluate_media(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { char *cp = instruction->text; char *mnemonic = NULL; sprintf(cp, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t", - address, opcode); + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t", + address, opcode); cp = strchr(cp, 0); /* parallel add/subtract */ @@ -725,11 +747,11 @@ static int evaluate_media(uint32_t opcode, uint32_t address, shift = "LSL"; } sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d", - type, COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - shift, imm); + type, COND(opcode), + (int) (opcode >> 12) & 0xf, + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + shift, imm); return ERROR_OK; } @@ -742,17 +764,16 @@ static int evaluate_media(uint32_t opcode, uint32_t address, shift = "ASR"; if (imm == 0) imm = 32; - } else { + } else shift = "LSL"; - } sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d", - (opcode & (1 << 22)) ? 'U' : 'S', - COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0x1f, - (int) (opcode >> 0) & 0xf, - shift, imm); + (opcode & (1 << 22)) ? 'U' : 'S', + COND(opcode), + (int) (opcode >> 12) & 0xf, + (int) (opcode >> 16) & 0x1f, + (int) (opcode >> 0) & 0xf, + shift, imm); return ERROR_OK; } @@ -768,110 +789,109 @@ static int evaluate_media(uint32_t opcode, uint32_t address, if (rn != 0xf) sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "X" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf, - rn); + (opcode & (1 << 6)) ? 'S' : 'A', + (opcode & (1 << 5)) ? "X" : "", + COND(opcode), + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + (int) (opcode >> 8) & 0xf, + rn); else sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d", + (opcode & (1 << 6)) ? 'S' : 'A', + (opcode & (1 << 5)) ? "X" : "", + COND(opcode), + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + (int) (opcode >> 8) & 0xf); + return ERROR_OK; + } + if ((opcode & 0x01f00000) == 0x01400000) { + sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d", (opcode & (1 << 6)) ? 'S' : 'A', (opcode & (1 << 5)) ? "X" : "", COND(opcode), + (int) (opcode >> 12) & 0xf, (int) (opcode >> 16) & 0xf, (int) (opcode >> 0) & 0xf, (int) (opcode >> 8) & 0xf); return ERROR_OK; } - if ((opcode & 0x01f00000) == 0x01400000) { - sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "X" : "", - COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); - return ERROR_OK; - } if ((opcode & 0x01f00000) == 0x01500000) { unsigned rn = (opcode >> 12) & 0xf; switch (opcode & 0xc0) { - case 3: - if (rn == 0xf) - goto undef; + case 3: + if (rn == 0xf) + goto undef; /* FALL THROUGH */ - case 0: - break; - default: - goto undef; + case 0: + break; + default: + goto undef; } if (rn != 0xf) sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "R" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf, - rn); + (opcode & (1 << 6)) ? 'S' : 'A', + (opcode & (1 << 5)) ? "R" : "", + COND(opcode), + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + (int) (opcode >> 8) & 0xf, + rn); else sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d", - (opcode & (1 << 5)) ? "R" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); + (opcode & (1 << 5)) ? "R" : "", + COND(opcode), + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + (int) (opcode >> 8) & 0xf); return ERROR_OK; } - /* simple matches against the remaining decode bits */ switch (opcode & 0x01f000f0) { - case 0x00a00030: - case 0x00e00030: - /* parallel halfword saturate */ - sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d", - (opcode & (1 << 22)) ? 'U' : 'S', - COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - return ERROR_OK; - case 0x00b00030: - mnemonic = "REV"; - break; - case 0x00b000b0: - mnemonic = "REV16"; - break; - case 0x00f000b0: - mnemonic = "REVSH"; - break; - case 0x008000b0: - /* select bytes */ - sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - return ERROR_OK; - case 0x01800010: - /* unsigned sum of absolute differences */ - if (((opcode >> 12) & 0xf) == 0xf) - sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode), + case 0x00a00030: + case 0x00e00030: + /* parallel halfword saturate */ + sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d", + (opcode & (1 << 22)) ? 'U' : 'S', + COND(opcode), + (int) (opcode >> 12) & 0xf, (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); - else - sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode), + (int) (opcode >> 0) & 0xf); + return ERROR_OK; + case 0x00b00030: + mnemonic = "REV"; + break; + case 0x00b000b0: + mnemonic = "REV16"; + break; + case 0x00f000b0: + mnemonic = "REVSH"; + break; + case 0x008000b0: + /* select bytes */ + sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode), + (int) (opcode >> 12) & 0xf, (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 12) & 0xf); - return ERROR_OK; + (int) (opcode >> 0) & 0xf); + return ERROR_OK; + case 0x01800010: + /* unsigned sum of absolute differences */ + if (((opcode >> 12) & 0xf) == 0xf) + sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode), + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + (int) (opcode >> 8) & 0xf); + else + sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode), + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, + (int) (opcode >> 8) & 0xf, + (int) (opcode >> 12) & 0xf); + return ERROR_OK; } if (mnemonic) { unsigned rm = (opcode >> 0) & 0xf; @@ -889,12 +909,12 @@ undef: /* Miscellaneous load/store instructions */ static int evaluate_misc_load_store(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t P, U, I, W, L, S, H; uint8_t Rn, Rd; - char *operation; /* "LDR" or "STR" */ - char *suffix; /* "H", "SB", "SH", "D" */ + char *operation;/* "LDR" or "STR" */ + char *suffix; /* "H", "SB", "SH", "D" */ char offset[32]; /* examine flags */ @@ -917,63 +937,46 @@ static int evaluate_misc_load_store(uint32_t opcode, instruction->info.load_store.U = U; /* determine instruction type and suffix */ - if (S) /* signed */ - { - if (L) /* load */ - { - if (H) - { + if (S) {/* signed */ + if (L) {/* load */ + if (H) { operation = "LDR"; instruction->type = ARM_LDRSH; suffix = "SH"; - } - else - { + } else { operation = "LDR"; instruction->type = ARM_LDRSB; suffix = "SB"; } - } - else /* there are no signed stores, so this is used to encode double-register load/stores */ - { + } else {/* there are no signed stores, so this is used to encode double-register + *load/stores */ suffix = "D"; - if (H) - { + if (H) { operation = "STR"; instruction->type = ARM_STRD; - } - else - { + } else { operation = "LDR"; instruction->type = ARM_LDRD; } } - } - else /* unsigned */ - { + } else {/* unsigned */ suffix = "H"; - if (L) /* load */ - { + if (L) {/* load */ operation = "LDR"; instruction->type = ARM_LDRH; - } - else /* store */ - { + } else {/* store */ operation = "STR"; instruction->type = ARM_STRH; } } - if (I) /* Immediate offset/index (#+-)*/ - { + 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; - } - else /* Register offset/index (+-) */ - { + } else {/* Register offset/index (+-) */ uint8_t Rm; Rm = (opcode & 0xf); snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm); @@ -984,30 +987,48 @@ static int evaluate_misc_load_store(uint32_t opcode, instruction->info.load_store.offset.reg.shift_imm = 0x0; } - if (P == 1) - { - if (W == 0) /* offset */ - { - 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); + if (P == 1) { + if (W == 0) { /* offset */ + 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 */ - { - 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); + } else {/* pre-indexed */ + 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; } - } - else /* post-indexed */ - { - 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); + } else {/* post-indexed */ + 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; } @@ -1017,7 +1038,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, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t P, U, S, W, L, Rn; uint32_t register_list; @@ -1041,82 +1062,68 @@ static int evaluate_ldm_stm(uint32_t opcode, instruction->info.load_store_multiple.S = S; instruction->info.load_store_multiple.W = W; - if (L) - { + if (L) { instruction->type = ARM_LDM; mnemonic = "LDM"; - } - else - { + } else { instruction->type = ARM_STM; mnemonic = "STM"; } - if (P) - { - if (U) - { + if (P) { + if (U) { instruction->info.load_store_multiple.addressing_mode = 1; addressing_mode = "IB"; - } - else - { + } else { instruction->info.load_store_multiple.addressing_mode = 3; addressing_mode = "DB"; } - } - else - { - if (U) - { + } else { + if (U) { instruction->info.load_store_multiple.addressing_mode = 0; /* "IA" is the default in UAL syntax */ addressing_mode = ""; - } - else - { + } else { instruction->info.load_store_multiple.addressing_mode = 2; addressing_mode = "DA"; } } reg_list_p = reg_list; - for (i = 0; i <= 15; i++) - { - if ((register_list >> i) & 1) - { - if (first_reg) - { + for (i = 0; i <= 15; i++) { + if ((register_list >> i) & 1) { + if (first_reg) { first_reg = 0; - reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), "r%i", i); - } - else - { - reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), ", r%i", i); - } + reg_list_p += snprintf(reg_list_p, + (reg_list + 69 - reg_list_p), + "r%i", + i); + } else + reg_list_p += snprintf(reg_list_p, + (reg_list + 69 - reg_list_p), + ", r%i", + i); } } 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) ? "^" : ""); + address, opcode, + mnemonic, addressing_mode, COND(opcode), + Rn, (W) ? "!" : "", reg_list, (S) ? "^" : ""); return ERROR_OK; } /* Multiplies, extra load/stores */ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { /* Multiply (accumulate) (long) and Swap/swap byte */ - if ((opcode & 0x000000f0) == 0x00000090) - { + if ((opcode & 0x000000f0) == 0x00000090) { /* Multiply (accumulate) */ - if ((opcode & 0x0f800000) == 0x00000000) - { + if ((opcode & 0x0f800000) == 0x00000000) { uint8_t Rm, Rs, Rn, Rd, S; Rm = opcode & 0xf; Rs = (opcode & 0xf00) >> 8; @@ -1125,26 +1132,39 @@ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, S = (opcode & 0x00100000) >> 20; /* examine A bit (accumulate) */ - if (opcode & 0x00200000) - { + if (opcode & 0x00200000) { instruction->type = ARM_MLA; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i", - address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn); - } - else - { + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i", + address, + opcode, + COND(opcode), + (S) ? "S" : "", + Rd, + Rm, + Rs, + Rn); + } else { instruction->type = ARM_MUL; - 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); + 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) - { - char* mnemonic = NULL; + if ((opcode & 0x0f800000) == 0x00800000) { + char *mnemonic = NULL; uint8_t Rm, Rs, RdHi, RdLow, S; Rm = opcode & 0xf; Rs = (opcode & 0xf00) >> 8; @@ -1152,8 +1172,7 @@ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, RdLow = (opcode & 0xf0000) >> 16; S = (opcode & 0x00100000) >> 20; - switch ((opcode & 0x00600000) >> 21) - { + switch ((opcode & 0x00600000) >> 21) { case 0x0: instruction->type = ARM_UMULL; mnemonic = "UMULL"; @@ -1172,16 +1191,24 @@ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, 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); + 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) - { + if ((opcode & 0x0f800000) == 0x01000000) { uint8_t Rm, Rd, Rn; Rm = opcode & 0xf; Rd = (opcode & 0xf000) >> 12; @@ -1190,8 +1217,16 @@ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, /* 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); + 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; } @@ -1201,54 +1236,64 @@ static int evaluate_mul_and_extra_ld_st(uint32_t opcode, } static int evaluate_mrs_msr(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { int R = (opcode & 0x00400000) >> 22; char *PSR = (R) ? "SPSR" : "CPSR"; /* Move register to status register (MSR) */ - if (opcode & 0x00200000) - { + if (opcode & 0x00200000) { instruction->type = ARM_MSR; /* immediate variant */ - if (opcode & 0x02000000) - { + 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" : "", - (opcode & 0x20000) ? "x" : "", - (opcode & 0x40000) ? "s" : "", - (opcode & 0x80000) ? "f" : "", - ror(immediate, (rotate * 2)) -); - } - else /* register variant */ - { + 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" : "", + (opcode & 0x20000) ? "x" : "", + (opcode & 0x40000) ? "s" : "", + (opcode & 0x80000) ? "f" : "", + ror(immediate, (rotate * 2)) + ); + } else {/* register variant */ uint8_t Rm = opcode & 0xf; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i", - address, opcode, COND(opcode), PSR, - (opcode & 0x10000) ? "c" : "", - (opcode & 0x20000) ? "x" : "", - (opcode & 0x40000) ? "s" : "", - (opcode & 0x80000) ? "f" : "", - Rm -); + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i", + address, + opcode, + COND(opcode), + PSR, + (opcode & 0x10000) ? "c" : "", + (opcode & 0x20000) ? "x" : "", + (opcode & 0x40000) ? "s" : "", + (opcode & 0x80000) ? "f" : "", + Rm + ); } - } - else /* Move status register to register (MRS) */ - { + } 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); + 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; @@ -1256,80 +1301,78 @@ static int evaluate_mrs_msr(uint32_t opcode, /* Miscellaneous instructions */ static int evaluate_misc_instr(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { /* MRS/MSR */ if ((opcode & 0x000000f0) == 0x00000000) - { evaluate_mrs_msr(opcode, address, instruction); - } /* BX */ - if ((opcode & 0x006000f0) == 0x00200010) - { + 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); + address, opcode, COND(opcode), Rm); instruction->info.b_bl_bx_blx.reg_operand = Rm; instruction->info.b_bl_bx_blx.target_address = -1; } /* BXJ - "Jazelle" support (ARMv5-J) */ - if ((opcode & 0x006000f0) == 0x00200020) - { + if ((opcode & 0x006000f0) == 0x00200020) { uint8_t Rm; instruction->type = ARM_BX; Rm = opcode & 0xf; snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i", - address, opcode, COND(opcode), Rm); + 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) - { + if ((opcode & 0x006000f0) == 0x00600010) { uint8_t Rm, Rd; instruction->type = ARM_CLZ; Rm = opcode & 0xf; Rd = (opcode & 0xf000) >> 12; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i", - address, opcode, COND(opcode), Rd, Rm); + 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) - { + 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); + 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) - { + if ((opcode & 0x0000000f0) == 0x00000050) { uint8_t Rm, Rd, Rn; char *mnemonic = NULL; Rm = opcode & 0xf; Rd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; - switch ((opcode & 0x00600000) >> 21) - { + switch ((opcode & 0x00600000) >> 21) { case 0x0: instruction->type = ARM_QADD; mnemonic = "QADD"; @@ -1348,30 +1391,39 @@ static int evaluate_misc_instr(uint32_t opcode, 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); + 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) - { + 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); + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "", + address, + opcode, + immediate); } /* Enhanced DSP multiplies */ - if ((opcode & 0x000000090) == 0x00000080) - { + if ((opcode & 0x000000090) == 0x00000080) { int x = (opcode & 0x20) >> 5; int y = (opcode & 0x40) >> 6; /* SMLA < x> */ - if ((opcode & 0x00600000) == 0x00000000) - { + if ((opcode & 0x00600000) == 0x00000000) { uint8_t Rd, Rm, Rs, Rn; instruction->type = ARM_SMLAxy; Rd = (opcode & 0xf0000) >> 16; @@ -1379,14 +1431,22 @@ static int evaluate_misc_instr(uint32_t opcode, 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); + 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) - { + if ((opcode & 0x00600000) == 0x00400000) { uint8_t RdLow, RdHi, Rm, Rs; instruction->type = ARM_SMLAxy; RdHi = (opcode & 0xf0000) >> 16; @@ -1394,14 +1454,22 @@ static int evaluate_misc_instr(uint32_t opcode, 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); + 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)) - { + if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) { uint8_t Rd, Rm, Rs, Rn; instruction->type = ARM_SMLAWy; Rd = (opcode & 0xf0000) >> 16; @@ -1409,37 +1477,58 @@ static int evaluate_misc_instr(uint32_t opcode, Rs = (opcode & 0xf00) >> 8; Rn = (opcode & 0xf000) >> 12; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i", - address, opcode, (y) ? "T" : "B", COND(opcode), - Rd, Rm, Rs, Rn); + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i", + address, + opcode, + (y) ? "T" : "B", + COND(opcode), + Rd, + Rm, + Rs, + Rn); } /* SMUL < x> */ - if ((opcode & 0x00600000) == 0x00300000) - { + if ((opcode & 0x00600000) == 0x00300000) { uint8_t Rd, Rm, Rs; instruction->type = ARM_SMULxy; 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); + 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)) - { + if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) { uint8_t Rd, Rm, Rs; instruction->type = ARM_SMULWy; 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); + 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); } } @@ -1447,7 +1536,7 @@ static int evaluate_misc_instr(uint32_t opcode, } static int evaluate_data_proc(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t I, op, S, Rn, Rd; char *mnemonic = NULL; @@ -1464,8 +1553,7 @@ static int evaluate_data_proc(uint32_t opcode, instruction->info.data_proc.Rn = Rn; instruction->info.data_proc.S = S; - switch (op) - { + switch (op) { case 0x0: instruction->type = ARM_AND; mnemonic = "AND"; @@ -1532,8 +1620,7 @@ static int evaluate_data_proc(uint32_t opcode, break; } - if (I) /* immediate shifter operand (#)*/ - { + if (I) {/* immediate shifter operand (#)*/ uint8_t immed_8 = opcode & 0xff; uint8_t rotate_imm = (opcode & 0xf00) >> 8; uint32_t immediate; @@ -1544,21 +1631,20 @@ static int evaluate_data_proc(uint32_t opcode, instruction->info.data_proc.variant = 0; instruction->info.data_proc.shifter_operand.immediate.immediate = immediate; - } - else /* register-based shifter operand */ - { + } else {/* register-based shifter operand */ uint8_t shift, Rm; shift = (opcode & 0x60) >> 5; Rm = (opcode & 0xf); - if ((opcode & 0x10) != 0x10) /* Immediate shifts ("" or ", #") */ - { + if ((opcode & 0x10) != 0x10) { /* Immediate shifts ("" or ", + *#") */ uint8_t shift_imm; shift_imm = (opcode & 0xf80) >> 7; instruction->info.data_proc.variant = 1; 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_imm = + shift_imm; instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift; /* LSR encodes a shift by 32 bit as 0x0 */ @@ -1574,35 +1660,36 @@ static int evaluate_data_proc(uint32_t opcode, shift = 0x4; if ((shift_imm == 0x0) && (shift == 0x0)) - { snprintf(shifter_operand, 32, "r%i", Rm); - } - else - { - if (shift == 0x0) /* LSL */ - { - snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm); - } - else if (shift == 0x1) /* LSR */ - { - snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm); - } - else if (shift == 0x2) /* ASR */ - { - snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm); - } - else if (shift == 0x3) /* ROR */ - { - snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm); - } - else if (shift == 0x4) /* RRX */ - { + else { + if (shift == 0x0) /* LSL */ + snprintf(shifter_operand, + 32, + "r%i, LSL #0x%x", + Rm, + shift_imm); + else if (shift == 0x1) /* LSR */ + snprintf(shifter_operand, + 32, + "r%i, LSR #0x%x", + Rm, + shift_imm); + else if (shift == 0x2) /* ASR */ + snprintf(shifter_operand, + 32, + "r%i, ASR #0x%x", + Rm, + shift_imm); + else if (shift == 0x3) /* ROR */ + snprintf(shifter_operand, + 32, + "r%i, ROR #0x%x", + Rm, + shift_imm); + else if (shift == 0x4) /* RRX */ snprintf(shifter_operand, 32, "r%i, RRX", Rm); - } } - } - else /* Register shifts (", ") */ - { + } else {/* Register shifts (", ") */ uint8_t Rs = (opcode & 0xf00) >> 8; instruction->info.data_proc.variant = 2; @@ -1610,52 +1697,60 @@ static int evaluate_data_proc(uint32_t opcode, instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs; instruction->info.data_proc.shifter_operand.register_shift.shift = shift; - if (shift == 0x0) /* LSL */ - { + if (shift == 0x0) /* LSL */ snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs); - } - else if (shift == 0x1) /* LSR */ - { + else if (shift == 0x1) /* LSR */ snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs); - } - else if (shift == 0x2) /* ASR */ - { + else if (shift == 0x2) /* ASR */ snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs); - } - else if (shift == 0x3) /* ROR */ - { + else if (shift == 0x3) /* ROR */ snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs); - } } } - 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", - address, opcode, mnemonic, COND(opcode), - (S) ? "S" : "", Rd, Rn, shifter_operand); - } - else if ((op == 0xd) || (op == 0xf)) /* {}{S} , */ - { - if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */ - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",address, opcode); + 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", + address, + opcode, + mnemonic, + COND(opcode), + (S) ? "S" : "", + Rd, + Rn, + shifter_operand); + } else if ((op == 0xd) || (op == 0xf)) { /* {}{S} , + * */ + if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */ + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP", + address, + opcode); else - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s", - address, opcode, mnemonic, COND(opcode), - (S) ? "S" : "", Rd, shifter_operand); - } - else /* {} , */ - { + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s", + address, + opcode, + mnemonic, + COND(opcode), + (S) ? "S" : "", + Rd, + shifter_operand); + } else {/* {} , */ snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s", - address, opcode, mnemonic, COND(opcode), - Rn, shifter_operand); + address, opcode, mnemonic, COND(opcode), + Rn, shifter_operand); } return ERROR_OK; } int arm_evaluate_opcode(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { /* clear fields, to avoid confusion */ memset(instruction, 0, sizeof(struct arm_instruction)); @@ -1663,8 +1758,7 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, instruction->instruction_size = 4; /* catch opcodes with condition field [31:28] = b1111 */ - if ((opcode & 0xf0000000) == 0xf0000000) - { + if ((opcode & 0xf0000000) == 0xf0000000) { /* Undefined instruction (or ARMv5E cache preload PLD) */ if ((opcode & 0x08000000) == 0x00000000) return evaluate_pld(opcode, address, instruction); @@ -1677,8 +1771,8 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, 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 */ + /* 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); @@ -1691,17 +1785,19 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, return evaluate_cdp_mcr_mrc(opcode, address, instruction); /* Undefined instruction */ - if ((opcode & 0x0f000000) == 0x0f000000) - { + if ((opcode & 0x0f000000) == 0x0f000000) { instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode); + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", + address, + opcode); return ERROR_OK; } } /* catch opcodes with [27:25] = b000 */ - if ((opcode & 0x0e000000) == 0x00000000) - { + if ((opcode & 0x0e000000) == 0x00000000) { /* Multiplies, extra load/stores */ if ((opcode & 0x00000090) == 0x00000090) return evaluate_mul_and_extra_ld_st(opcode, address, instruction); @@ -1714,13 +1810,15 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, } /* catch opcodes with [27:25] = b001 */ - if ((opcode & 0x0e000000) == 0x02000000) - { + if ((opcode & 0x0e000000) == 0x02000000) { /* Undefined instruction */ - if ((opcode & 0x0fb00000) == 0x03000000) - { + if ((opcode & 0x0fb00000) == 0x03000000) { instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode); + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", + address, + opcode); return ERROR_OK; } @@ -1733,15 +1831,13 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, } /* catch opcodes with [27:25] = b010 */ - if ((opcode & 0x0e000000) == 0x04000000) - { + 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) - { + if ((opcode & 0x0e000000) == 0x06000000) { /* Load/store register offset */ if ((opcode & 0x00000010) == 0x00000000) return evaluate_load_store(opcode, address, instruction); @@ -1749,12 +1845,11 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, /* Architecturally Undefined instruction * ... don't expect these to ever be used */ - if ((opcode & 0x07f000f0) == 0x07f000f0) - { + if ((opcode & 0x07f000f0) == 0x07f000f0) { instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF", - address, opcode); + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF", + address, opcode); return ERROR_OK; } @@ -1763,29 +1858,25 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, } /* catch opcodes with [27:25] = b100 */ - if ((opcode & 0x0e000000) == 0x08000000) - { + if ((opcode & 0x0e000000) == 0x08000000) { /* Load/store multiple */ return evaluate_ldm_stm(opcode, address, instruction); } /* catch opcodes with [27:25] = b101 */ - if ((opcode & 0x0e000000) == 0x0a000000) - { + 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) == 0x0c000000) - { + if ((opcode & 0x0e000000) == 0x0c000000) { /* 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) - { + if ((opcode & 0x0e000000) == 0x0e000000) { /* Software interrupt */ if ((opcode & 0x0f000000) == 0x0f000000) return evaluate_swi(opcode, address, instruction); @@ -1805,7 +1896,7 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, } static int evaluate_b_bl_blx_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = opcode & 0x7ff; uint32_t opc = (opcode >> 11) & 0x3; @@ -1818,8 +1909,7 @@ static int evaluate_b_bl_blx_thumb(uint16_t opcode, target_address = address + 4 + (offset << 1); - switch (opc) - { + switch (opc) { /* unconditional branch */ case 0: instruction->type = ARM_B; @@ -1864,7 +1954,7 @@ static int evaluate_b_bl_blx_thumb(uint16_t opcode, } static int evaluate_add_sub_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t Rd = (opcode >> 0) & 0x7; uint8_t Rn = (opcode >> 3) & 0x7; @@ -1873,13 +1963,10 @@ static int evaluate_add_sub_thumb(uint16_t opcode, uint32_t reg_imm = opcode & (1 << 10); char *mnemonic; - if (opc) - { + if (opc) { instruction->type = ARM_SUB; mnemonic = "SUBS"; - } - else - { + } else { /* REVISIT: if reg_imm == 0, display as "MOVS" */ instruction->type = ARM_ADD; mnemonic = "ADDS"; @@ -1889,28 +1976,25 @@ static int evaluate_add_sub_thumb(uint16_t opcode, instruction->info.data_proc.Rn = Rn; instruction->info.data_proc.S = 1; - if (reg_imm) - { - instruction->info.data_proc.variant = 0; /*immediate*/ + if (reg_imm) { + instruction->info.data_proc.variant = 0;/*immediate*/ instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d", - address, opcode, mnemonic, Rd, Rn, Rm_imm); - } - else - { - instruction->info.data_proc.variant = 1; /*immediate shift*/ + "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d", + address, opcode, mnemonic, Rd, Rn, Rm_imm); + } else { + instruction->info.data_proc.variant = 1;/*immediate shift*/ instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i", - address, opcode, mnemonic, Rd, Rn, Rm_imm); + "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i", + address, opcode, mnemonic, Rd, Rn, Rm_imm); } return ERROR_OK; } static int evaluate_shift_imm_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t Rd = (opcode >> 0) & 0x7; uint8_t Rm = (opcode >> 3) & 0x7; @@ -1918,8 +2002,7 @@ static int evaluate_shift_imm_thumb(uint16_t opcode, uint8_t opc = (opcode >> 11) & 0x3; char *mnemonic = NULL; - switch (opc) - { + switch (opc) { case 0: instruction->type = ARM_MOV; mnemonic = "LSLS"; @@ -1944,19 +2027,19 @@ static int evaluate_shift_imm_thumb(uint16_t opcode, instruction->info.data_proc.Rn = -1; instruction->info.data_proc.S = 1; - instruction->info.data_proc.variant = 1; /*immediate_shift*/ + instruction->info.data_proc.variant = 1;/*immediate_shift*/ instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm; instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x" , + "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x", address, opcode, mnemonic, Rd, Rm, imm); return ERROR_OK; } static int evaluate_data_proc_imm_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t imm = opcode & 0xff; uint8_t Rd = (opcode >> 8) & 0x7; @@ -1966,11 +2049,10 @@ static int evaluate_data_proc_imm_thumb(uint16_t opcode, 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.variant = 0;/*immediate*/ instruction->info.data_proc.shifter_operand.immediate.immediate = imm; - switch (opc) - { + switch (opc) { case 0: instruction->type = ARM_MOV; mnemonic = "MOVS"; @@ -1999,9 +2081,9 @@ static int evaluate_data_proc_imm_thumb(uint16_t opcode, } static int evaluate_data_proc_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { - uint8_t high_reg, op, Rm, Rd,H1,H2; + uint8_t high_reg, op, Rm, Rd, H1, H2; char *mnemonic = NULL; bool nop = false; @@ -2016,17 +2098,15 @@ static int evaluate_data_proc_thumb(uint16_t opcode, instruction->info.data_proc.Rd = Rd; instruction->info.data_proc.Rn = Rd; instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP)); - instruction->info.data_proc.variant = 1 /*immediate shift*/; + instruction->info.data_proc.variant = 1 /*immediate shift*/; instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm; - if (high_reg) - { + if (high_reg) { Rd |= H1 << 3; Rm |= H2 << 3; op >>= 2; - switch (op) - { + switch (op) { case 0x0: instruction->type = ARM_ADD; mnemonic = "ADD"; @@ -2042,43 +2122,34 @@ static int evaluate_data_proc_thumb(uint16_t opcode, nop = true; break; case 0x3: - if ((opcode & 0x7) == 0x0) - { + if ((opcode & 0x7) == 0x0) { instruction->info.b_bl_bx_blx.reg_operand = Rm; - if (H1) - { + if (H1) { instruction->type = ARM_BLX; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 - " 0x%4.4x \tBLX\tr%i", - address, opcode, Rm); - } - else - { + "0x%8.8" PRIx32 + " 0x%4.4x \tBLX\tr%i", + address, opcode, Rm); + } else { instruction->type = ARM_BX; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 - " 0x%4.4x \tBX\tr%i", - address, opcode, Rm); + "0x%8.8" PRIx32 + " 0x%4.4x \tBX\tr%i", + address, opcode, Rm); } - } - else - { + } else { instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 - " 0x%4.4x \t" - "UNDEFINED INSTRUCTION", - address, opcode); + "0x%8.8" PRIx32 + " 0x%4.4x \t" + "UNDEFINED INSTRUCTION", + address, opcode); } return ERROR_OK; break; } - } - else - { - switch (op) - { + } else { + switch (op) { case 0x0: instruction->type = ARM_AND; mnemonic = "ANDS"; @@ -2090,7 +2161,7 @@ static int evaluate_data_proc_thumb(uint16_t opcode, case 0x2: instruction->type = ARM_MOV; mnemonic = "LSLS"; - instruction->info.data_proc.variant = 2 /*register shift*/; + instruction->info.data_proc.variant = 2 /*register shift*/; instruction->info.data_proc.shifter_operand.register_shift.shift = 0; instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; @@ -2098,7 +2169,7 @@ static int evaluate_data_proc_thumb(uint16_t opcode, case 0x3: instruction->type = ARM_MOV; mnemonic = "LSRS"; - instruction->info.data_proc.variant = 2 /*register shift*/; + instruction->info.data_proc.variant = 2 /*register shift*/; instruction->info.data_proc.shifter_operand.register_shift.shift = 1; instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; @@ -2106,7 +2177,7 @@ static int evaluate_data_proc_thumb(uint16_t opcode, case 0x4: instruction->type = ARM_MOV; mnemonic = "ASRS"; - instruction->info.data_proc.variant = 2 /*register shift*/; + instruction->info.data_proc.variant = 2 /*register shift*/; instruction->info.data_proc.shifter_operand.register_shift.shift = 2; instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; @@ -2122,7 +2193,7 @@ static int evaluate_data_proc_thumb(uint16_t opcode, case 0x7: instruction->type = ARM_MOV; mnemonic = "RORS"; - instruction->info.data_proc.variant = 2 /*register shift*/; + instruction->info.data_proc.variant = 2 /*register shift*/; instruction->info.data_proc.shifter_operand.register_shift.shift = 3; instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; @@ -2134,7 +2205,7 @@ static int evaluate_data_proc_thumb(uint16_t opcode, case 0x9: instruction->type = ARM_RSB; mnemonic = "RSBS"; - instruction->info.data_proc.variant = 0 /*immediate*/; + instruction->info.data_proc.variant = 0 /*immediate*/; instruction->info.data_proc.shifter_operand.immediate.immediate = 0; instruction->info.data_proc.Rn = Rm; break; @@ -2169,11 +2240,11 @@ static int evaluate_data_proc_thumb(uint16_t opcode, snprintf(instruction->text, 128, "0x%8.8" PRIx32 " 0x%4.4x \tNOP\t\t\t" "; (%s r%i, r%i)", - address, opcode, mnemonic, Rd, Rm); + address, opcode, mnemonic, Rd, Rm); else snprintf(instruction->text, 128, "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i", - address, opcode, mnemonic, Rd, Rm); + address, opcode, mnemonic, Rd, Rm); return ERROR_OK; } @@ -2185,7 +2256,7 @@ static inline uint32_t thumb_alignpc4(uint32_t addr) } static int evaluate_load_literal_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t immediate; uint8_t Rd = (opcode >> 8) & 0x7; @@ -2196,21 +2267,21 @@ static int evaluate_load_literal_thumb(uint16_t opcode, instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = 15 /*PC*/; - instruction->info.load_store.index_mode = 0; /*offset*/ - instruction->info.load_store.offset_mode = 0; /*immediate*/ + instruction->info.load_store.index_mode = 0; /*offset*/ + instruction->info.load_store.offset_mode = 0; /*immediate*/ instruction->info.load_store.offset.offset = immediate; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t" - "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32, - address, opcode, Rd, immediate, - thumb_alignpc4(address) + immediate); + "0x%8.8" PRIx32 " 0x%4.4x \t" + "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32, + address, opcode, Rd, immediate, + thumb_alignpc4(address) + immediate); return ERROR_OK; } static int evaluate_load_store_reg_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint8_t Rd = (opcode >> 0) & 0x7; uint8_t Rn = (opcode >> 3) & 0x7; @@ -2218,8 +2289,7 @@ static int evaluate_load_store_reg_thumb(uint16_t opcode, uint8_t opc = (opcode >> 9) & 0x7; char *mnemonic = NULL; - switch (opc) - { + switch (opc) { case 0: instruction->type = ARM_STR; mnemonic = "STR"; @@ -2260,15 +2330,15 @@ static int evaluate_load_store_reg_thumb(uint16_t opcode, instruction->info.load_store.Rd = Rd; instruction->info.load_store.Rn = Rn; - instruction->info.load_store.index_mode = 0; /*offset*/ - instruction->info.load_store.offset_mode = 1; /*register*/ + instruction->info.load_store.index_mode = 0; /*offset*/ + instruction->info.load_store.offset_mode = 1; /*register*/ instruction->info.load_store.offset.reg.Rm = Rm; return ERROR_OK; } static int evaluate_load_store_imm_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = (opcode >> 6) & 0x1f; uint8_t Rd = (opcode >> 0) & 0x7; @@ -2279,75 +2349,66 @@ static int evaluate_load_store_imm_thumb(uint16_t opcode, char suffix = ' '; uint32_t shift = 2; - if (L) - { + if (L) { instruction->type = ARM_LDR; mnemonic = "LDR"; - } - else - { + } else { instruction->type = ARM_STR; mnemonic = "STR"; } - if ((opcode&0xF000) == 0x8000) - { + if ((opcode&0xF000) == 0x8000) { suffix = 'H'; shift = 1; - } - else if (B) - { + } else if (B) { suffix = 'B'; shift = 0; } snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" PRIx32 "]", - address, opcode, mnemonic, suffix, Rd, Rn, offset << shift); + "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" 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*/ - instruction->info.load_store.offset_mode = 0; /*immediate*/ + instruction->info.load_store.index_mode = 0; /*offset*/ + instruction->info.load_store.offset_mode = 0; /*immediate*/ instruction->info.load_store.offset.offset = offset << shift; return ERROR_OK; } static int evaluate_load_store_stack_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = opcode & 0xff; uint8_t Rd = (opcode >> 8) & 0x7; uint32_t L = opcode & (1 << 11); char *mnemonic; - if (L) - { + if (L) { instruction->type = ARM_LDR; mnemonic = "LDR"; - } - else - { + } else { instruction->type = ARM_STR; mnemonic = "STR"; } snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" PRIx32 "]", - address, opcode, mnemonic, Rd, offset*4); + "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" 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*/ - instruction->info.load_store.offset_mode = 0; /*immediate*/ + instruction->info.load_store.index_mode = 0; /*offset*/ + instruction->info.load_store.offset_mode = 0; /*immediate*/ instruction->info.load_store.offset.offset = offset*4; return ERROR_OK; } static int evaluate_add_sp_pc_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t imm = opcode & 0xff; uint8_t Rd = (opcode >> 8) & 0x7; @@ -2357,22 +2418,19 @@ static int evaluate_add_sp_pc_thumb(uint16_t opcode, instruction->type = ARM_ADD; - if (SP) - { + if (SP) { reg_name = "SP"; Rn = 13; - } - else - { + } else { reg_name = "PC"; Rn = 15; } snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32, - address, opcode, Rd, reg_name, imm * 4); + "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32, + address, opcode, Rd, reg_name, imm * 4); - instruction->info.data_proc.variant = 0 /* immediate */; + instruction->info.data_proc.variant = 0 /* immediate */; instruction->info.data_proc.Rd = Rd; instruction->info.data_proc.Rn = Rn; instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4; @@ -2381,20 +2439,17 @@ static int evaluate_add_sp_pc_thumb(uint16_t opcode, } static int evaluate_adjust_stack_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t imm = opcode & 0x7f; uint8_t opc = opcode & (1 << 7); char *mnemonic; - if (opc) - { + if (opc) { instruction->type = ARM_SUB; mnemonic = "SUB"; - } - else - { + } else { instruction->type = ARM_ADD; mnemonic = "ADD"; } @@ -2403,7 +2458,7 @@ static int evaluate_adjust_stack_thumb(uint16_t opcode, "0x%8.8" PRIx32 " 0x%4.4x \t%s\tSP, #%#" PRIx32, address, opcode, mnemonic, imm*4); - instruction->info.data_proc.variant = 0 /* immediate */; + instruction->info.data_proc.variant = 0 /* immediate */; instruction->info.data_proc.Rd = 13 /*SP*/; instruction->info.data_proc.Rn = 13 /*SP*/; instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4; @@ -2412,7 +2467,7 @@ static int evaluate_adjust_stack_thumb(uint16_t opcode, } static int evaluate_breakpoint_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t imm = opcode & 0xff; @@ -2426,7 +2481,7 @@ static int evaluate_breakpoint_thumb(uint16_t opcode, } static int evaluate_load_store_multiple_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t reg_list = opcode & 0xff; uint32_t L = opcode & (1 << 11); @@ -2443,53 +2498,46 @@ static int evaluate_load_store_multiple_thumb(uint16_t opcode, * The STMIA and LDMIA opcodes are used for other instructions. */ - if ((opcode & 0xf000) == 0xc000) - { /* generic load/store multiple */ + if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */ char *wback = "!"; - if (L) - { + if (L) { instruction->type = ARM_LDM; mnemonic = "LDM"; if (opcode & (1 << Rn)) wback = ""; - } - else - { + } else { instruction->type = ARM_STM; mnemonic = "STM"; } snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback); - } - else - { /* push/pop */ - Rn = 13; /* SP */ - if (L) - { + } else {/* push/pop */ + Rn = 13;/* SP */ + if (L) { instruction->type = ARM_LDM; mnemonic = "POP"; if (R) reg_list |= (1 << 15) /*PC*/; - } - else - { + } else { instruction->type = ARM_STM; mnemonic = "PUSH"; - addr_mode = 3; /*DB*/ + addr_mode = 3; /*DB*/ if (R) reg_list |= (1 << 14) /*LR*/; } } reg_names_p = reg_names; - for (i = 0; i <= 15; i++) - { + for (i = 0; i <= 15; i++) { if (reg_list & (1 << i)) - reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i); + reg_names_p += snprintf(reg_names_p, + (reg_names + 40 - reg_names_p), + "r%i, ", + i); } if (reg_names_p > reg_names) reg_names_p[-2] = '\0'; - else /* invalid op : no registers */ + else /* invalid op : no registers */ reg_names[0] = '\0'; snprintf(instruction->text, 128, @@ -2504,26 +2552,23 @@ static int evaluate_load_store_multiple_thumb(uint16_t opcode, } static int evaluate_cond_branch_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) + uint32_t address, struct arm_instruction *instruction) { uint32_t offset = opcode & 0xff; uint8_t cond = (opcode >> 8) & 0xf; uint32_t target_address; - if (cond == 0xf) - { + if (cond == 0xf) { instruction->type = ARM_SWI; snprintf(instruction->text, 128, "0x%8.8" PRIx32 " 0x%4.4x \tSVC\t%#2.2" PRIx32, address, opcode, offset); return ERROR_OK; - } - else if (cond == 0xe) - { + } else if (cond == 0xe) { instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION", - address, opcode); + "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION", + address, opcode); return ERROR_OK; } @@ -2546,7 +2591,7 @@ static int evaluate_cond_branch_thumb(uint16_t opcode, } static int evaluate_cb_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { unsigned offset; @@ -2564,7 +2609,7 @@ static int evaluate_cb_thumb(uint16_t opcode, uint32_t address, } static int evaluate_extend_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { /* added in ARMv6 */ snprintf(instruction->text, 128, @@ -2578,7 +2623,7 @@ static int evaluate_extend_thumb(uint16_t opcode, uint32_t address, } static int evaluate_cps_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { /* added in ARMv6 */ if ((opcode & 0x0ff0) == 0x0650) @@ -2586,7 +2631,7 @@ static int evaluate_cps_thumb(uint16_t opcode, uint32_t address, "0x%8.8" PRIx32 " 0x%4.4x \tSETEND %s", address, opcode, (opcode & 0x80) ? "BE" : "LE"); - else /* ASSUME (opcode & 0x0fe0) == 0x0660 */ + else /* ASSUME (opcode & 0x0fe0) == 0x0660 */ snprintf(instruction->text, 128, "0x%8.8" PRIx32 " 0x%4.4x \tCPSI%c\t%s%s%s", address, opcode, @@ -2599,21 +2644,21 @@ static int evaluate_cps_thumb(uint16_t opcode, uint32_t address, } static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { char *suffix; /* added in ARMv6 */ switch ((opcode >> 6) & 3) { - case 0: - suffix = ""; - break; - case 1: - suffix = "16"; - break; - default: - suffix = "SH"; - break; + case 0: + suffix = ""; + break; + case 1: + suffix = "16"; + break; + default: + suffix = "SH"; + break; } snprintf(instruction->text, 128, "0x%8.8" PRIx32 " 0x%4.4x \tREV%s\tr%d, r%d", @@ -2624,29 +2669,29 @@ static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address, } static int evaluate_hint_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { char *hint; switch ((opcode >> 4) & 0x0f) { - case 0: - hint = "NOP"; - break; - case 1: - hint = "YIELD"; - break; - case 2: - hint = "WFE"; - break; - case 3: - hint = "WFI"; - break; - case 4: - hint = "SEV"; - break; - default: - hint = "HINT (UNRECOGNIZED)"; - break; + case 0: + hint = "NOP"; + break; + case 1: + hint = "YIELD"; + break; + case 2: + hint = "WFE"; + break; + case 3: + hint = "WFI"; + break; + case 4: + hint = "SEV"; + break; + default: + hint = "HINT (UNRECOGNIZED)"; + break; } snprintf(instruction->text, 128, @@ -2657,7 +2702,7 @@ static int evaluate_hint_thumb(uint16_t opcode, uint32_t address, } static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) + struct arm_instruction *instruction) { unsigned cond = (opcode >> 4) & 0x0f; char *x = "", *y = "", *z = ""; @@ -2688,8 +2733,7 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruct instruction->opcode = opcode; instruction->instruction_size = 2; - if ((opcode & 0xe000) == 0x0000) - { + if ((opcode & 0xe000) == 0x0000) { /* add/substract register or immediate */ if ((opcode & 0x1800) == 0x1800) return evaluate_add_sub_thumb(opcode, address, instruction); @@ -2700,118 +2744,94 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruct /* 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) - { return evaluate_load_literal_thumb(opcode, address, instruction); - } /* Load/Store register offset */ if ((opcode & 0xf000) == 0x5000) - { return evaluate_load_store_reg_thumb(opcode, address, instruction); - } /* Load/Store immediate offset */ if (((opcode & 0xe000) == 0x6000) - ||((opcode & 0xf000) == 0x8000)) - { + || ((opcode & 0xf000) == 0x8000)) return evaluate_load_store_imm_thumb(opcode, address, instruction); - } /* Load/Store from/to stack */ if ((opcode & 0xf000) == 0x9000) - { return evaluate_load_store_stack_thumb(opcode, address, instruction); - } /* Add to SP/PC */ if ((opcode & 0xf000) == 0xa000) - { return evaluate_add_sp_pc_thumb(opcode, address, instruction); - } /* Misc */ - if ((opcode & 0xf000) == 0xb000) - { + if ((opcode & 0xf000) == 0xb000) { switch ((opcode >> 8) & 0x0f) { - case 0x0: - return evaluate_adjust_stack_thumb(opcode, address, instruction); - case 0x1: - case 0x3: - case 0x9: - case 0xb: - return evaluate_cb_thumb(opcode, address, instruction); - case 0x2: - return evaluate_extend_thumb(opcode, address, instruction); - case 0x4: - case 0x5: - case 0xc: - case 0xd: - return evaluate_load_store_multiple_thumb(opcode, address, - instruction); - case 0x6: - return evaluate_cps_thumb(opcode, address, instruction); - case 0xa: - if ((opcode & 0x00c0) == 0x0080) - break; - return evaluate_byterev_thumb(opcode, address, instruction); - case 0xe: - return evaluate_breakpoint_thumb(opcode, address, instruction); - case 0xf: - if (opcode & 0x000f) - return evaluate_ifthen_thumb(opcode, address, - instruction); - else - return evaluate_hint_thumb(opcode, address, - instruction); + case 0x0: + return evaluate_adjust_stack_thumb(opcode, address, instruction); + case 0x1: + case 0x3: + case 0x9: + case 0xb: + return evaluate_cb_thumb(opcode, address, instruction); + case 0x2: + return evaluate_extend_thumb(opcode, address, instruction); + case 0x4: + case 0x5: + case 0xc: + case 0xd: + return evaluate_load_store_multiple_thumb(opcode, address, + instruction); + case 0x6: + return evaluate_cps_thumb(opcode, address, instruction); + case 0xa: + if ((opcode & 0x00c0) == 0x0080) + break; + return evaluate_byterev_thumb(opcode, address, instruction); + case 0xe: + return evaluate_breakpoint_thumb(opcode, address, instruction); + case 0xf: + if (opcode & 0x000f) + return evaluate_ifthen_thumb(opcode, address, + instruction); + else + return evaluate_hint_thumb(opcode, address, + instruction); } instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION", - address, opcode); + "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION", + address, opcode); return ERROR_OK; } /* Load/Store multiple */ if ((opcode & 0xf000) == 0xc000) - { return evaluate_load_store_multiple_thumb(opcode, address, instruction); - } /* Conditional branch + SWI */ if ((opcode & 0xf000) == 0xd000) - { return evaluate_cond_branch_thumb(opcode, address, instruction); - } - if ((opcode & 0xe000) == 0xe000) - { + if ((opcode & 0xe000) == 0xe000) { /* Undefined instructions */ - if ((opcode & 0xf801) == 0xe801) - { + if ((opcode & 0xf801) == 0xe801) { instruction->type = ARM_UNDEFINED_INSTRUCTION; snprintf(instruction->text, 128, "0x%8.8" PRIx32 " 0x%8.8x\t" "UNDEFINED INSTRUCTION", address, opcode); return ERROR_OK; - } - else - { /* Branch to offset */ + } else /* Branch to offset */ return evaluate_b_bl_blx_thumb(opcode, address, instruction); - } } LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode); @@ -2819,7 +2839,7 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruct } static int t2ev_b_bl(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned offset; unsigned b21 = 1 << 21; @@ -2860,7 +2880,7 @@ static int t2ev_b_bl(uint32_t opcode, uint32_t address, } static int t2ev_cond_b(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned offset; unsigned b17 = 1 << 17; @@ -2902,54 +2922,54 @@ static const char *special_name(int number) char *special = "(RESERVED)"; switch (number) { - case 0: - special = "apsr"; - break; - case 1: - special = "iapsr"; - break; - case 2: - special = "eapsr"; - break; - case 3: - special = "xpsr"; - break; - case 5: - special = "ipsr"; - break; - case 6: - special = "epsr"; - break; - case 7: - special = "iepsr"; - break; - case 8: - special = "msp"; - break; - case 9: - special = "psp"; - break; - case 16: - special = "primask"; - break; - case 17: - special = "basepri"; - break; - case 18: - special = "basepri_max"; - break; - case 19: - special = "faultmask"; - break; - case 20: - special = "control"; - break; + case 0: + special = "apsr"; + break; + case 1: + special = "iapsr"; + break; + case 2: + special = "eapsr"; + break; + case 3: + special = "xpsr"; + break; + case 5: + special = "ipsr"; + break; + case 6: + special = "epsr"; + break; + case 7: + special = "iepsr"; + break; + case 8: + special = "msp"; + break; + case 9: + special = "psp"; + break; + case 16: + special = "primask"; + break; + case 17: + special = "basepri"; + break; + case 18: + special = "basepri_max"; + break; + case 19: + special = "faultmask"; + break; + case 20: + special = "control"; + break; } return special; } static int t2ev_hint(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { const char *mnemonic; @@ -2965,62 +2985,62 @@ static int t2ev_hint(uint32_t opcode, uint32_t address, } switch (opcode & 0x0f) { - case 0: - mnemonic = "NOP.W"; - break; - case 1: - mnemonic = "YIELD.W"; - break; - case 2: - mnemonic = "WFE.W"; - break; - case 3: - mnemonic = "WFI.W"; - break; - case 4: - mnemonic = "SEV.W"; - break; - default: - mnemonic = "HINT.W (UNRECOGNIZED)"; - break; + case 0: + mnemonic = "NOP.W"; + break; + case 1: + mnemonic = "YIELD.W"; + break; + case 2: + mnemonic = "WFE.W"; + break; + case 3: + mnemonic = "WFI.W"; + break; + case 4: + mnemonic = "SEV.W"; + break; + default: + mnemonic = "HINT.W (UNRECOGNIZED)"; + break; } strcpy(cp, mnemonic); return ERROR_OK; } static int t2ev_misc(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { const char *mnemonic; switch ((opcode >> 4) & 0x0f) { - case 0: - mnemonic = "LEAVEX"; - break; - case 1: - mnemonic = "ENTERX"; - break; - case 2: - mnemonic = "CLREX"; - break; - case 4: - mnemonic = "DSB"; - break; - case 5: - mnemonic = "DMB"; - break; - case 6: - mnemonic = "ISB"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + case 0: + mnemonic = "LEAVEX"; + break; + case 1: + mnemonic = "ENTERX"; + break; + case 2: + mnemonic = "CLREX"; + break; + case 4: + mnemonic = "DSB"; + break; + case 5: + mnemonic = "DMB"; + break; + case 6: + mnemonic = "ISB"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } strcpy(cp, mnemonic); return ERROR_OK; } static int t2ev_b_misc(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { /* permanently undefined */ if ((opcode & 0x07f07000) == 0x07f02000) { @@ -3030,37 +3050,37 @@ static int t2ev_b_misc(uint32_t opcode, uint32_t address, } switch ((opcode >> 12) & 0x5) { - case 0x1: - case 0x5: - return t2ev_b_bl(opcode, address, instruction, cp); - case 0x4: - goto undef; - case 0: - if (((opcode >> 23) & 0x07) != 0x07) - return t2ev_cond_b(opcode, address, instruction, cp); - if (opcode & (1 << 26)) + case 0x1: + case 0x5: + return t2ev_b_bl(opcode, address, instruction, cp); + case 0x4: goto undef; - break; + case 0: + if (((opcode >> 23) & 0x07) != 0x07) + return t2ev_cond_b(opcode, address, instruction, cp); + if (opcode & (1 << 26)) + goto undef; + break; } switch ((opcode >> 20) & 0x7f) { - case 0x38: - case 0x39: - sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff), + case 0x38: + case 0x39: + sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff), (int) (opcode >> 16) & 0x0f); - return ERROR_OK; - case 0x3a: - return t2ev_hint(opcode, address, instruction, cp); - case 0x3b: - return t2ev_misc(opcode, address, instruction, cp); - case 0x3c: - sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f); - return ERROR_OK; - case 0x3e: - case 0x3f: - sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f, + return ERROR_OK; + case 0x3a: + return t2ev_hint(opcode, address, instruction, cp); + case 0x3b: + return t2ev_misc(opcode, address, instruction, cp); + case 0x3c: + sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f); + return ERROR_OK; + case 0x3e: + case 0x3f: + sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f, special_name(opcode & 0xff)); - return ERROR_OK; + return ERROR_OK; } undef: @@ -3068,7 +3088,7 @@ undef: } static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { char *mnemonic = NULL; int rn = (opcode >> 16) & 0xf; @@ -3088,123 +3108,123 @@ static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address, /* "Modified" immediates */ switch (func >> 1) { - case 0: - break; - case 2: - immed <<= 8; + case 0: + break; + case 2: + immed <<= 8; /* FALLTHROUGH */ - case 1: - immed += immed << 16; - break; - case 3: - immed += immed << 8; - immed += immed << 16; - break; - default: - immed |= 0x80; - immed = ror(immed, func); + case 1: + immed += immed << 16; + break; + case 3: + immed += immed << 8; + immed += immed << 16; + break; + default: + immed |= 0x80; + immed = ror(immed, func); } if (opcode & (1 << 20)) suffix = "S"; switch ((opcode >> 21) & 0xf) { - case 0: - if (rd == 0xf) { - instruction->type = ARM_TST; - mnemonic = "TST"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_AND; - mnemonic = "AND"; - } - break; - case 1: - instruction->type = ARM_BIC; - mnemonic = "BIC"; - break; - case 2: - if (rn == 0xf) { - instruction->type = ARM_MOV; - mnemonic = "MOV"; - one = true; + case 0: + if (rd == 0xf) { + instruction->type = ARM_TST; + mnemonic = "TST"; + one = true; + suffix = ""; + rd = rn; + } else { + instruction->type = ARM_AND; + mnemonic = "AND"; + } + break; + case 1: + instruction->type = ARM_BIC; + mnemonic = "BIC"; + break; + case 2: + if (rn == 0xf) { + instruction->type = ARM_MOV; + mnemonic = "MOV"; + one = true; + suffix2 = ".W"; + } else { + instruction->type = ARM_ORR; + mnemonic = "ORR"; + } + break; + case 3: + if (rn == 0xf) { + instruction->type = ARM_MVN; + mnemonic = "MVN"; + one = true; + } else { + /* instruction->type = ARM_ORN; */ + mnemonic = "ORN"; + } + break; + case 4: + if (rd == 0xf) { + instruction->type = ARM_TEQ; + mnemonic = "TEQ"; + one = true; + suffix = ""; + rd = rn; + } else { + instruction->type = ARM_EOR; + mnemonic = "EOR"; + } + break; + case 8: + if (rd == 0xf) { + instruction->type = ARM_CMN; + mnemonic = "CMN"; + one = true; + suffix = ""; + rd = rn; + } else { + instruction->type = ARM_ADD; + mnemonic = "ADD"; + suffix2 = ".W"; + } + break; + case 10: + instruction->type = ARM_ADC; + mnemonic = "ADC"; suffix2 = ".W"; - } else { - instruction->type = ARM_ORR; - mnemonic = "ORR"; - } - break; - case 3: - if (rn == 0xf) { - instruction->type = ARM_MVN; - mnemonic = "MVN"; - one = true; - } else { - // instruction->type = ARM_ORN; - mnemonic = "ORN"; - } - break; - case 4: - if (rd == 0xf) { - instruction->type = ARM_TEQ; - mnemonic = "TEQ"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_EOR; - mnemonic = "EOR"; - } - break; - case 8: - if (rd == 0xf) { - instruction->type = ARM_CMN; - mnemonic = "CMN"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_ADD; - mnemonic = "ADD"; + break; + case 11: + instruction->type = ARM_SBC; + mnemonic = "SBC"; + break; + case 13: + if (rd == 0xf) { + instruction->type = ARM_CMP; + mnemonic = "CMP"; + one = true; + suffix = ""; + rd = rn; + } else { + instruction->type = ARM_SUB; + mnemonic = "SUB"; + } suffix2 = ".W"; - } - break; - case 10: - instruction->type = ARM_ADC; - mnemonic = "ADC"; - suffix2 = ".W"; - break; - case 11: - instruction->type = ARM_SBC; - mnemonic = "SBC"; - break; - case 13: - if (rd == 0xf) { - instruction->type = ARM_CMP; - mnemonic = "CMP"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_SUB; - mnemonic = "SUB"; - } - suffix2 = ".W"; - break; - case 14: - instruction->type = ARM_RSB; - mnemonic = "RSB"; - suffix2 = ".W"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + break; + case 14: + instruction->type = ARM_RSB; + mnemonic = "RSB"; + suffix2 = ".W"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } if (one) sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x", - mnemonic, suffix2 ,rd, immed, immed); + mnemonic, suffix2, rd, immed, immed); else sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x", mnemonic, suffix, suffix2, @@ -3214,7 +3234,7 @@ static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address, } static int t2ev_data_immed(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { char *mnemonic = NULL; int rn = (opcode >> 16) & 0xf; @@ -3228,67 +3248,67 @@ static int t2ev_data_immed(uint32_t opcode, uint32_t address, immed |= (1 << 11); switch ((opcode >> 20) & 0x1f) { - case 0: - if (rn == 0xf) { - add = true; - goto do_adr; - } - mnemonic = "ADDW"; - break; - case 4: - immed |= (opcode >> 4) & 0xf000; - sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed); - return ERROR_OK; - case 0x0a: - if (rn == 0xf) - goto do_adr; - mnemonic = "SUBW"; - break; - case 0x0c: - /* move constant to top 16 bits of register */ - immed |= (opcode >> 4) & 0xf000; - sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed); - return ERROR_OK; - case 0x10: - case 0x12: - is_signed = true; - case 0x18: - case 0x1a: - /* signed/unsigned saturated add */ - immed = (opcode >> 6) & 0x03; - immed |= (opcode >> 10) & 0x1c; - sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t", + case 0: + if (rn == 0xf) { + add = true; + goto do_adr; + } + mnemonic = "ADDW"; + break; + case 4: + immed |= (opcode >> 4) & 0xf000; + sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed); + return ERROR_OK; + case 0x0a: + if (rn == 0xf) + goto do_adr; + mnemonic = "SUBW"; + break; + case 0x0c: + /* move constant to top 16 bits of register */ + immed |= (opcode >> 4) & 0xf000; + sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed); + return ERROR_OK; + case 0x10: + case 0x12: + is_signed = true; + case 0x18: + case 0x1a: + /* signed/unsigned saturated add */ + immed = (opcode >> 6) & 0x03; + immed |= (opcode >> 10) & 0x1c; + sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t", is_signed ? "S" : "U", rd, (int) (opcode & 0x1f) + is_signed, rn, (opcode & (1 << 21)) ? "ASR" : "LSL", immed ? immed : 32); - return ERROR_OK; - case 0x14: - is_signed = true; + return ERROR_OK; + case 0x14: + is_signed = true; /* FALLTHROUGH */ - case 0x1c: - /* signed/unsigned bitfield extract */ - immed = (opcode >> 6) & 0x03; - immed |= (opcode >> 10) & 0x1c; - sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t", + case 0x1c: + /* signed/unsigned bitfield extract */ + immed = (opcode >> 6) & 0x03; + immed |= (opcode >> 10) & 0x1c; + sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t", is_signed ? "S" : "U", rd, rn, immed, (int) (opcode & 0x1f) + 1); - return ERROR_OK; - case 0x16: - immed = (opcode >> 6) & 0x03; - immed |= (opcode >> 10) & 0x1c; - if (rn == 0xf) /* bitfield clear */ - sprintf(cp, "BFC\tr%d, #%d, #%d\t", - rd, immed, - (int) (opcode & 0x1f) + 1 - immed); - else /* bitfield insert */ - sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t", - rd, rn, immed, - (int) (opcode & 0x1f) + 1 - immed); - return ERROR_OK; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + return ERROR_OK; + case 0x16: + immed = (opcode >> 6) & 0x03; + immed |= (opcode >> 10) & 0x1c; + if (rn == 0xf) /* bitfield clear */ + sprintf(cp, "BFC\tr%d, #%d, #%d\t", + rd, immed, + (int) (opcode & 0x1f) + 1 - immed); + else /* bitfield insert */ + sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t", + rd, rn, immed, + (int) (opcode & 0x1f) + 1 - immed); + return ERROR_OK; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic, @@ -3309,7 +3329,7 @@ do_adr: } static int t2ev_store_single(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned op = (opcode >> 20) & 0xf; char *size = ""; @@ -3326,39 +3346,39 @@ static int t2ev_store_single(uint32_t opcode, uint32_t address, if (opcode & 0x0800) op |= 1; switch (op) { - /* byte */ - case 0x8: - case 0x9: - size = "B"; - goto imm12; - case 0x1: - size = "B"; - goto imm8; - case 0x0: - size = "B"; - break; - /* halfword */ - case 0xa: - case 0xb: - size = "H"; - goto imm12; - case 0x3: - size = "H"; - goto imm8; - case 0x2: - size = "H"; - break; - /* word */ - case 0xc: - case 0xd: - goto imm12; - case 0x5: - goto imm8; - case 0x4: - break; - /* error */ - default: - return ERROR_COMMAND_SYNTAX_ERROR; + /* byte */ + case 0x8: + case 0x9: + size = "B"; + goto imm12; + case 0x1: + size = "B"; + goto imm8; + case 0x0: + size = "B"; + break; + /* halfword */ + case 0xa: + case 0xb: + size = "H"; + goto imm12; + case 0x3: + size = "H"; + goto imm8; + case 0x2: + size = "H"; + break; + /* word */ + case 0xc: + case 0xd: + goto imm12; + case 0x5: + goto imm8; + case 0x4: + break; + /* error */ + default: + return ERROR_COMMAND_SYNTAX_ERROR; } sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]", @@ -3376,12 +3396,12 @@ imm8: immed = opcode & 0x00ff; switch (opcode & 0x700) { - case 0x600: - suffix = "T"; - break; - case 0x000: - case 0x200: - return ERROR_COMMAND_SYNTAX_ERROR; + case 0x600: + suffix = "T"; + break; + case 0x000: + case 0x200: + return ERROR_COMMAND_SYNTAX_ERROR; } /* two indexed modes will write back rn */ @@ -3402,74 +3422,74 @@ imm8: } static int t2ev_mul32(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int ra = (opcode >> 12) & 0xf; switch (opcode & 0x007000f0) { - case 0: - if (ra == 0xf) - sprintf(cp, "MUL\tr%d, r%d, r%d", - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - else - sprintf(cp, "MLA\tr%d, r%d, r%d, r%d", + case 0: + if (ra == 0xf) + sprintf(cp, "MUL\tr%d, r%d, r%d", + (int) (opcode >> 8) & 0xf, + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf); + else + sprintf(cp, "MLA\tr%d, r%d, r%d, r%d", + (int) (opcode >> 8) & 0xf, + (int) (opcode >> 16) & 0xf, + (int) (opcode >> 0) & 0xf, ra); + break; + case 0x10: + sprintf(cp, "MLS\tr%d, r%d, r%d, r%d", (int) (opcode >> 8) & 0xf, (int) (opcode >> 16) & 0xf, (int) (opcode >> 0) & 0xf, ra); - break; - case 0x10: - sprintf(cp, "MLS\tr%d, r%d, r%d, r%d", - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, ra); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } return ERROR_OK; } static int t2ev_mul64_div(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int op = (opcode >> 4) & 0xf; char *infix = "MUL"; op += (opcode >> 16) & 0x70; switch (op) { - case 0x40: - case 0x60: - infix = "MLA"; + case 0x40: + case 0x60: + infix = "MLA"; /* FALLTHROUGH */ - case 0: - case 0x20: - sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d", + case 0: + case 0x20: + sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d", (op & 0x20) ? 'U' : 'S', infix, (int) (opcode >> 12) & 0xf, (int) (opcode >> 8) & 0xf, (int) (opcode >> 16) & 0xf, (int) (opcode >> 0) & 0xf); - break; - case 0x1f: - case 0x3f: - sprintf(cp, "%cDIV\tr%d, r%d, r%d", + break; + case 0x1f: + case 0x3f: + sprintf(cp, "%cDIV\tr%d, r%d, r%d", (op & 0x20) ? 'U' : 'S', (int) (opcode >> 8) & 0xf, (int) (opcode >> 16) & 0xf, (int) (opcode >> 0) & 0xf); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } return ERROR_OK; } static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int op = (opcode >> 22) & 0x6; @@ -3481,42 +3501,42 @@ static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, op |= 1; switch (op) { - case 0: - mode = "DB"; + case 0: + mode = "DB"; /* FALL THROUGH */ - case 6: - sprintf(cp, "SRS%s\tsp%s, #%d", mode, + case 6: + sprintf(cp, "SRS%s\tsp%s, #%d", mode, t ? "!" : "", (unsigned) (opcode & 0x1f)); - return ERROR_OK; - case 1: - mode = "DB"; + return ERROR_OK; + case 1: + mode = "DB"; /* FALL THROUGH */ - case 7: - sprintf(cp, "RFE%s\tr%d%s", mode, + 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; - case 3: - if (rn == 13 && t) - sprintf(cp, "POP.W\t"); - else - sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : ""); - break; - case 4: - if (rn == 13 && t) - sprintf(cp, "PUSH.W\t"); - else - sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : ""); - break; - case 5: - sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : ""); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + return ERROR_OK; + case 2: + sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : ""); + break; + case 3: + if (rn == 13 && t) + sprintf(cp, "POP.W\t"); + else + sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : ""); + break; + case 4: + if (rn == 13 && t) + sprintf(cp, "PUSH.W\t"); + else + sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : ""); + break; + case 5: + sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : ""); + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } cp = strchr(cp, 0); @@ -3536,7 +3556,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, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { unsigned op1op2 = (opcode >> 20) & 0x3; unsigned op3 = (opcode >> 4) & 0xf; @@ -3550,64 +3570,64 @@ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address, op1op2 |= (opcode >> 21) & 0xc; switch (op1op2) { - case 0: - mnemonic = "STREX"; - goto strex; - case 1: - mnemonic = "LDREX"; - goto ldrex; - case 2: - case 6: - case 8: - case 10: - case 12: - case 14: - mnemonic = "STRD"; - goto immediate; - case 3: - case 7: - case 9: - case 11: - case 13: - case 15: - mnemonic = "LDRD"; - if (rn == 15) - goto literal; - else - goto immediate; - case 4: - switch (op3) { - case 4: - mnemonic = "STREXB"; - break; - case 5: - mnemonic = "STREXH"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - rd = opcode & 0xf; - imm = 0; - goto strex; - case 5: - switch (op3) { case 0: - sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf); - return ERROR_OK; + mnemonic = "STREX"; + goto strex; case 1: - sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf); - return ERROR_OK; + mnemonic = "LDREX"; + goto ldrex; + case 2: + case 6: + case 8: + case 10: + case 12: + case 14: + mnemonic = "STRD"; + goto immediate; + case 3: + case 7: + case 9: + case 11: + case 13: + case 15: + mnemonic = "LDRD"; + if (rn == 15) + goto literal; + else + goto immediate; case 4: - mnemonic = "LDREXB"; - break; + switch (op3) { + case 4: + mnemonic = "STREXB"; + break; + case 5: + mnemonic = "STREXH"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } + rd = opcode & 0xf; + imm = 0; + goto strex; case 5: - mnemonic = "LDREXH"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - imm = 0; - goto ldrex; + switch (op3) { + case 0: + sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf); + return ERROR_OK; + case 1: + sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf); + return ERROR_OK; + case 4: + mnemonic = "LDREXB"; + break; + case 5: + mnemonic = "LDREXH"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } + imm = 0; + goto ldrex; } return ERROR_COMMAND_SYNTAX_ERROR; @@ -3662,7 +3682,7 @@ literal: } static int t2ev_data_shift(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int op = (opcode >> 21) & 0xf; int rd = (opcode >> 8) & 0xf; @@ -3677,187 +3697,187 @@ static int t2ev_data_shift(uint32_t opcode, uint32_t address, suffix = "S"; switch (op) { - case 0: - if (rd == 0xf) { - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_TST; - mnemonic = "TST"; - suffix = ""; - goto two; - } - instruction->type = ARM_AND; - mnemonic = "AND"; - break; - case 1: - instruction->type = ARM_BIC; - mnemonic = "BIC"; - break; - case 2: - if (rn == 0xf) { - instruction->type = ARM_MOV; - switch (type) { - case 0: - if (immed == 0) { - sprintf(cp, "MOV%s.W\tr%d, r%d", - suffix, rd, - (int) (opcode & 0xf)); - return ERROR_OK; - } - mnemonic = "LSL"; - break; - case 1: - mnemonic = "LSR"; - break; - case 2: - mnemonic = "ASR"; - break; - default: - if (immed == 0) { - sprintf(cp, "RRX%s\tr%d, r%d", - suffix, rd, - (int) (opcode & 0xf)); - return ERROR_OK; + case 0: + if (rd == 0xf) { + if (!(opcode & (1 << 20))) + return ERROR_COMMAND_SYNTAX_ERROR; + instruction->type = ARM_TST; + mnemonic = "TST"; + suffix = ""; + goto two; + } + instruction->type = ARM_AND; + mnemonic = "AND"; + break; + case 1: + instruction->type = ARM_BIC; + mnemonic = "BIC"; + break; + case 2: + if (rn == 0xf) { + instruction->type = ARM_MOV; + switch (type) { + case 0: + if (immed == 0) { + sprintf(cp, "MOV%s.W\tr%d, r%d", + suffix, rd, + (int) (opcode & 0xf)); + return ERROR_OK; + } + mnemonic = "LSL"; + break; + case 1: + mnemonic = "LSR"; + break; + case 2: + mnemonic = "ASR"; + break; + default: + if (immed == 0) { + sprintf(cp, "RRX%s\tr%d, r%d", + suffix, rd, + (int) (opcode & 0xf)); + return ERROR_OK; + } + mnemonic = "ROR"; + break; } - mnemonic = "ROR"; - break; + goto immediate; + } else { + instruction->type = ARM_ORR; + mnemonic = "ORR"; } - goto immediate; - } else { - instruction->type = ARM_ORR; - mnemonic = "ORR"; - } - break; - case 3: - if (rn == 0xf) { - instruction->type = ARM_MVN; - mnemonic = "MVN"; - rn = rd; - goto two; - } else { - // instruction->type = ARM_ORN; - mnemonic = "ORN"; - } - break; - case 4: - if (rd == 0xf) { - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_TEQ; - mnemonic = "TEQ"; - suffix = ""; - goto two; - } - instruction->type = ARM_EOR; - mnemonic = "EOR"; - break; - case 8: - if (rd == 0xf) { - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_CMN; - mnemonic = "CMN"; - suffix = ""; - goto two; - } - instruction->type = ARM_ADD; - mnemonic = "ADD"; - break; - case 0xa: - instruction->type = ARM_ADC; - mnemonic = "ADC"; - break; - case 0xb: - instruction->type = ARM_SBC; - mnemonic = "SBC"; - break; - case 0xd: - if (rd == 0xf) { - if (!(opcode & (1 << 21))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_CMP; - mnemonic = "CMP"; - suffix = ""; - goto two; - } - instruction->type = ARM_SUB; - mnemonic = "SUB"; - break; - case 0xe: - instruction->type = ARM_RSB; - mnemonic = "RSB"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + break; + case 3: + if (rn == 0xf) { + instruction->type = ARM_MVN; + mnemonic = "MVN"; + rn = rd; + goto two; + } else { + /* instruction->type = ARM_ORN; */ + mnemonic = "ORN"; + } + break; + case 4: + if (rd == 0xf) { + if (!(opcode & (1 << 20))) + return ERROR_COMMAND_SYNTAX_ERROR; + instruction->type = ARM_TEQ; + mnemonic = "TEQ"; + suffix = ""; + goto two; + } + instruction->type = ARM_EOR; + mnemonic = "EOR"; + break; + case 8: + if (rd == 0xf) { + if (!(opcode & (1 << 20))) + return ERROR_COMMAND_SYNTAX_ERROR; + instruction->type = ARM_CMN; + mnemonic = "CMN"; + suffix = ""; + goto two; + } + instruction->type = ARM_ADD; + mnemonic = "ADD"; + break; + case 0xa: + instruction->type = ARM_ADC; + mnemonic = "ADC"; + break; + case 0xb: + instruction->type = ARM_SBC; + mnemonic = "SBC"; + break; + case 0xd: + if (rd == 0xf) { + if (!(opcode & (1 << 21))) + return ERROR_COMMAND_SYNTAX_ERROR; + instruction->type = ARM_CMP; + mnemonic = "CMP"; + suffix = ""; + goto two; + } + instruction->type = ARM_SUB; + mnemonic = "SUB"; + break; + case 0xe: + instruction->type = ARM_RSB; + mnemonic = "RSB"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } sprintf(cp, "%s%s.W\tr%d, r%d, r%d", - mnemonic, suffix, rd, rn, (int) (opcode & 0xf)); + mnemonic, suffix, rd, rn, (int) (opcode & 0xf)); shift: cp = strchr(cp, 0); switch (type) { - case 0: - if (immed == 0) - return ERROR_OK; - suffix = "LSL"; - break; - case 1: - suffix = "LSR"; - if (immed == 32) - immed = 0; - break; - case 2: - suffix = "ASR"; - if (immed == 32) - immed = 0; - break; - case 3: - if (immed == 0) { - strcpy(cp, ", RRX"); - return ERROR_OK; - } - suffix = "ROR"; - break; + case 0: + if (immed == 0) + return ERROR_OK; + suffix = "LSL"; + break; + case 1: + suffix = "LSR"; + if (immed == 32) + immed = 0; + break; + case 2: + suffix = "ASR"; + if (immed == 32) + immed = 0; + break; + case 3: + if (immed == 0) { + strcpy(cp, ", RRX"); + return ERROR_OK; + } + suffix = "ROR"; + break; } sprintf(cp, ", %s #%d", suffix, immed ? immed : 32); return ERROR_OK; two: sprintf(cp, "%s%s.W\tr%d, r%d", - mnemonic, suffix, rn, (int) (opcode & 0xf)); + mnemonic, suffix, rn, (int) (opcode & 0xf)); goto shift; immediate: sprintf(cp, "%s%s.W\tr%d, r%d, #%d", - mnemonic, suffix, rd, - (int) (opcode & 0xf), immed ? immed : 32); + mnemonic, suffix, rd, + (int) (opcode & 0xf), immed ? immed : 32); return ERROR_OK; } static int t2ev_data_reg(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { char *mnemonic; - char * suffix = ""; + char *suffix = ""; if (((opcode >> 4) & 0xf) == 0) { switch ((opcode >> 21) & 0x7) { - case 0: - mnemonic = "LSL"; - break; - case 1: - mnemonic = "LSR"; - break; - case 2: - mnemonic = "ASR"; - break; - case 3: - mnemonic = "ROR"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + case 0: + mnemonic = "LSL"; + break; + case 1: + mnemonic = "LSR"; + break; + case 2: + mnemonic = "ASR"; + break; + case 3: + mnemonic = "ROR"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } instruction->type = ARM_MOV; @@ -3871,66 +3891,66 @@ static int t2ev_data_reg(uint32_t opcode, uint32_t address, } else if (opcode & (1 << 7)) { switch ((opcode >> 20) & 0xf) { - case 0: - case 1: - case 4: - case 5: - switch ((opcode >> 4) & 0x3) { + case 0: case 1: - suffix = ", ROR #8"; - break; - case 2: - suffix = ", ROR #16"; - break; - case 3: - suffix = ", ROR #24"; - break; - } - sprintf(cp, "%cXT%c.W\tr%d, r%d%s", + case 4: + case 5: + switch ((opcode >> 4) & 0x3) { + case 1: + suffix = ", ROR #8"; + break; + case 2: + suffix = ", ROR #16"; + break; + case 3: + suffix = ", ROR #24"; + break; + } + sprintf(cp, "%cXT%c.W\tr%d, r%d%s", (opcode & (1 << 24)) ? 'U' : 'S', (opcode & (1 << 26)) ? 'B' : 'H', (int) (opcode >> 8) & 0xf, (int) (opcode >> 0) & 0xf, suffix); - break; - case 8: - case 9: - case 0xa: - case 0xb: - if (opcode & (1 << 6)) - return ERROR_COMMAND_SYNTAX_ERROR; - if (((opcode >> 12) & 0xf) != 0xf) - return ERROR_COMMAND_SYNTAX_ERROR; - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - - switch (((opcode >> 19) & 0x04) - | ((opcode >> 4) & 0x3)) { - case 0: - mnemonic = "REV.W"; break; - case 1: - mnemonic = "REV16.W"; - break; - case 2: - mnemonic = "RBIT"; - break; - case 3: - mnemonic = "REVSH.W"; - break; - case 4: - mnemonic = "CLZ"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - sprintf(cp, "%s\tr%d, r%d", + case 8: + case 9: + case 0xa: + case 0xb: + if (opcode & (1 << 6)) + return ERROR_COMMAND_SYNTAX_ERROR; + if (((opcode >> 12) & 0xf) != 0xf) + return ERROR_COMMAND_SYNTAX_ERROR; + if (!(opcode & (1 << 20))) + return ERROR_COMMAND_SYNTAX_ERROR; + + switch (((opcode >> 19) & 0x04) + | ((opcode >> 4) & 0x3)) { + case 0: + mnemonic = "REV.W"; + break; + case 1: + mnemonic = "REV16.W"; + break; + case 2: + mnemonic = "RBIT"; + break; + case 3: + mnemonic = "REVSH.W"; + break; + case 4: + mnemonic = "CLZ"; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } + sprintf(cp, "%s\tr%d, r%d", mnemonic, (int) (opcode >> 8) & 0xf, (int) (opcode >> 0) & 0xf); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; } } @@ -3938,7 +3958,7 @@ static int t2ev_data_reg(uint32_t opcode, uint32_t address, } static int t2ev_load_word(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int immed; @@ -4012,7 +4032,7 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address, } static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int rt = (opcode >> 12) & 0xf; @@ -4022,176 +4042,176 @@ static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address, char *mnemonic; switch ((opcode >> 23) & 0x3) { - case 0: - if ((rn & rt) == 0xf) { + case 0: + if ((rn & rt) == 0xf) { pld_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "PLD\tr%d, %#8.8" PRIx32, - rt, address); - return ERROR_OK; - } - if (rn == 0x0f && rt != 0x0f) { + immed = opcode & 0xfff; + address = thumb_alignpc4(address); + if (opcode & (1 << 23)) + address += immed; + else + address -= immed; + sprintf(cp, "PLD\tr%d, %#8.8" PRIx32, + rt, address); + return ERROR_OK; + } + if (rn == 0x0f && rt != 0x0f) { ldrb_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32, - rt, address); - return ERROR_OK; - } - if (rn == 0x0f) - break; - if ((op2 & 0x3c) == 0x38) { - immed = opcode & 0xff; - sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x", - rt, rn, immed, immed); - return ERROR_OK; - } - if ((op2 & 0x3c) == 0x30) { - if (rt == 0x0f) { + immed = opcode & 0xfff; + address = thumb_alignpc4(address); + if (opcode & (1 << 23)) + address += immed; + else + address -= immed; + sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32, + rt, address); + return ERROR_OK; + } + if (rn == 0x0f) + break; + if ((op2 & 0x3c) == 0x38) { immed = opcode & 0xff; - immed = -immed; -preload_immediate: - p1 = (opcode & (1 << 21)) ? "W" : ""; - sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x", - p1, rn, immed, immed); + sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x", + rt, rn, immed, immed); return ERROR_OK; } - mnemonic = "LDRB"; + if ((op2 & 0x3c) == 0x30) { + if (rt == 0x0f) { + immed = opcode & 0xff; + immed = -immed; +preload_immediate: + p1 = (opcode & (1 << 21)) ? "W" : ""; + sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x", + p1, rn, immed, immed); + return ERROR_OK; + } + mnemonic = "LDRB"; ldrxb_immediate_t3: - immed = opcode & 0xff; - if (!(opcode & 0x200)) - immed = -immed; - - /* two indexed modes will write back rn */ - if (opcode & 0x100) { - if (opcode & 0x400) /* pre-indexed */ - p2 = "]!"; - else { /* post-indexed */ - p1 = "]"; - p2 = ""; + immed = opcode & 0xff; + if (!(opcode & 0x200)) + immed = -immed; + + /* two indexed modes will write back rn */ + if (opcode & 0x100) { + if (opcode & 0x400) /* pre-indexed */ + p2 = "]!"; + else { /* post-indexed */ + p1 = "]"; + p2 = ""; + } } - } ldrxb_immediate_t2: - sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x", - mnemonic, rt, rn, p1, - immed, p2, immed); - return ERROR_OK; - } - if ((op2 & 0x24) == 0x24) { - mnemonic = "LDRB"; - goto ldrxb_immediate_t3; - } - if (op2 == 0) { - int rm = opcode & 0xf; + sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x", + mnemonic, rt, rn, p1, + immed, p2, immed); + return ERROR_OK; + } + if ((op2 & 0x24) == 0x24) { + mnemonic = "LDRB"; + goto ldrxb_immediate_t3; + } + if (op2 == 0) { + int rm = opcode & 0xf; - if (rt == 0x0f) - sprintf(cp, "PLD\t"); - else - sprintf(cp, "LDRB.W\tr%d, ", rt); - immed = (opcode >> 4) & 0x3; - cp = strchr(cp, 0); - sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed); - return ERROR_OK; - } - break; - case 1: - if ((rn & rt) == 0xf) - goto pld_literal; - if (rt == 0xf) { - immed = opcode & 0xfff; - goto preload_immediate; - } - if (rn == 0x0f) - goto ldrb_literal; - mnemonic = "LDRB.W"; - immed = opcode & 0xfff; - goto ldrxb_immediate_t2; - case 2: - if ((rn & rt) == 0xf) { - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "PLI\t%#8.8" PRIx32, address); - return ERROR_OK; - } - if (rn == 0xf && rt != 0xf) { -ldrsb_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "LDRSB\t%#8.8" PRIx32, address); - return ERROR_OK; - } - if (rn == 0xf) + if (rt == 0x0f) + sprintf(cp, "PLD\t"); + else + sprintf(cp, "LDRB.W\tr%d, ", rt); + immed = (opcode >> 4) & 0x3; + cp = strchr(cp, 0); + sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed); + return ERROR_OK; + } break; - if ((op2 & 0x3c) == 0x38) { - immed = opcode & 0xff; - sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x", - rt, rn, immed, immed); - return ERROR_OK; - } - if ((op2 & 0x3c) == 0x30) { + case 1: + if ((rn & rt) == 0xf) + goto pld_literal; if (rt == 0xf) { + immed = opcode & 0xfff; + goto preload_immediate; + } + if (rn == 0x0f) + goto ldrb_literal; + mnemonic = "LDRB.W"; + immed = opcode & 0xfff; + goto ldrxb_immediate_t2; + case 2: + if ((rn & rt) == 0xf) { + immed = opcode & 0xfff; + address = thumb_alignpc4(address); + if (opcode & (1 << 23)) + address += immed; + else + address -= immed; + sprintf(cp, "PLI\t%#8.8" PRIx32, address); + return ERROR_OK; + } + if (rn == 0xf && rt != 0xf) { +ldrsb_literal: + immed = opcode & 0xfff; + address = thumb_alignpc4(address); + if (opcode & (1 << 23)) + address += immed; + else + address -= immed; + sprintf(cp, "LDRSB\t%#8.8" PRIx32, address); + return ERROR_OK; + } + if (rn == 0xf) + break; + if ((op2 & 0x3c) == 0x38) { immed = opcode & 0xff; - immed = -immed; // pli - sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x", - rn, immed, -immed); + sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x", + rt, rn, immed, immed); return ERROR_OK; } - mnemonic = "LDRSB"; - goto ldrxb_immediate_t3; - } - if ((op2 & 0x24) == 0x24) { - mnemonic = "LDRSB"; - goto ldrxb_immediate_t3; - } - if (op2 == 0) { - int rm = opcode & 0xf; + if ((op2 & 0x3c) == 0x30) { + if (rt == 0xf) { + immed = opcode & 0xff; + immed = -immed; /* pli */ + sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x", + rn, immed, -immed); + return ERROR_OK; + } + mnemonic = "LDRSB"; + goto ldrxb_immediate_t3; + } + if ((op2 & 0x24) == 0x24) { + mnemonic = "LDRSB"; + goto ldrxb_immediate_t3; + } + if (op2 == 0) { + int rm = opcode & 0xf; - if (rt == 0x0f) - sprintf(cp, "PLI\t"); - else - sprintf(cp, "LDRSB.W\tr%d, ", rt); - immed = (opcode >> 4) & 0x3; - cp = strchr(cp, 0); - sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed); - return ERROR_OK; - } - break; - case 3: - if (rt == 0xf) { + if (rt == 0x0f) + sprintf(cp, "PLI\t"); + else + sprintf(cp, "LDRSB.W\tr%d, ", rt); + immed = (opcode >> 4) & 0x3; + cp = strchr(cp, 0); + sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed); + return ERROR_OK; + } + break; + case 3: + if (rt == 0xf) { + immed = opcode & 0xfff; + sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x", + rn, immed, immed); + return ERROR_OK; + } + if (rn == 0xf) + goto ldrsb_literal; immed = opcode & 0xfff; - sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x", - rn, immed, immed); - return ERROR_OK; - } - if (rn == 0xf) - goto ldrsb_literal; - immed = opcode & 0xfff; - mnemonic = "LDRSB"; - goto ldrxb_immediate_t2; + mnemonic = "LDRSB"; + goto ldrxb_immediate_t2; } return ERROR_COMMAND_SYNTAX_ERROR; } static int t2ev_load_halfword(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) + struct arm_instruction *instruction, char *cp) { int rn = (opcode >> 16) & 0xf; int rt = (opcode >> 12) & 0xf; @@ -4292,21 +4312,21 @@ int thumb2_opcode(struct target *target, uint32_t address, struct arm_instructio return retval; switch (op & 0xf800) { - case 0xf800: - case 0xf000: - case 0xe800: - /* 32-bit instructions */ - instruction->instruction_size = 4; - opcode = op << 16; - retval = target_read_u16(target, address + 2, &op); - if (retval != ERROR_OK) - return retval; - opcode |= op; - instruction->opcode = opcode; - break; - default: - /* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */ - return thumb_evaluate_opcode(op, address, instruction); + case 0xf800: + case 0xf000: + case 0xe800: + /* 32-bit instructions */ + instruction->instruction_size = 4; + opcode = op << 16; + retval = target_read_u16(target, address + 2, &op); + if (retval != ERROR_OK) + return retval; + opcode |= op; + instruction->opcode = opcode; + break; + default: + /* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */ + return thumb_evaluate_opcode(op, address, instruction); } snprintf(instruction->text, 128, @@ -4356,7 +4376,7 @@ int thumb2_opcode(struct target *target, uint32_t address, struct arm_instructio retval = t2ev_data_shift(opcode, address, instruction, cp); /* ARMv7-M: A5.3.12 Data processing (register) - * and A5.3.13 Miscellaneous operations + * and A5.3.13 Miscellaneous operations */ else if ((opcode & 0x1f000000) == 0x1a000000) retval = t2ev_data_reg(opcode, address, instruction, cp); @@ -4393,34 +4413,26 @@ int thumb2_opcode(struct target *target, uint32_t address, struct arm_instructio int arm_access_size(struct arm_instruction *instruction) { if ((instruction->type == ARM_LDRB) - || (instruction->type == ARM_LDRBT) - || (instruction->type == ARM_LDRSB) - || (instruction->type == ARM_STRB) - || (instruction->type == ARM_STRBT)) - { + || (instruction->type == ARM_LDRBT) + || (instruction->type == ARM_LDRSB) + || (instruction->type == ARM_STRB) + || (instruction->type == ARM_STRBT)) return 1; - } else if ((instruction->type == ARM_LDRH) - || (instruction->type == ARM_LDRSH) - || (instruction->type == ARM_STRH)) - { + || (instruction->type == ARM_LDRSH) + || (instruction->type == ARM_STRH)) return 2; - } else if ((instruction->type == ARM_LDR) - || (instruction->type == ARM_LDRT) - || (instruction->type == ARM_STR) - || (instruction->type == ARM_STRT)) - { + || (instruction->type == ARM_LDRT) + || (instruction->type == ARM_STR) + || (instruction->type == ARM_STRT)) return 4; - } else if ((instruction->type == ARM_LDRD) - || (instruction->type == ARM_STRD)) - { + || (instruction->type == ARM_STRD)) return 8; - } - else - { - LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type); + else { + LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", + instruction->type); return 0; } }