X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm_disassembler.c;h=17948d6da49beecd893c997e544f8d9a0e9eebdd;hp=5cec6d67aad7335f0bbac196b800bd50392f86d2;hb=b50fa9a19d0b600d26b6cbca57cd94c7b89f941c;hpb=34b32d613af913645bdb0b0e79f10bf0f302ff33 diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 5cec6d67aa..17948d6da4 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -15,9 +15,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -131,6 +129,59 @@ static int evaluate_pld(uint32_t opcode, return ERROR_OK; } + /* DSB */ + if ((opcode & 0x07f000f0) == 0x05700040) { + instruction->type = ARM_DSB; + + char *opt; + switch (opcode & 0x0000000f) { + case 0xf: + opt = "SY"; + break; + case 0xe: + opt = "ST"; + break; + case 0xb: + opt = "ISH"; + break; + case 0xa: + opt = "ISHST"; + break; + case 0x7: + opt = "NSH"; + break; + case 0x6: + opt = "NSHST"; + break; + case 0x3: + opt = "OSH"; + break; + case 0x2: + opt = "OSHST"; + break; + default: + opt = "UNK"; + } + + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB %s", + address, opcode, opt); + + return ERROR_OK; + } + /* ISB */ + if ((opcode & 0x07f000f0) == 0x05700060) { + instruction->type = ARM_ISB; + + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB %s", + address, opcode, + ((opcode & 0x0000000f) == 0xf) ? "SY" : "UNK"); + + return ERROR_OK; + } return evaluate_unknown(opcode, address, instruction); } @@ -1498,7 +1549,7 @@ static int evaluate_misc_instr(uint32_t opcode, } /* SMLAW < y> */ - if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) { + if (((opcode & 0x00600000) == 0x00200000) && (x == 0)) { uint8_t Rd, Rm, Rs, Rn; instruction->type = ARM_SMLAWy; Rd = (opcode & 0xf0000) >> 16; @@ -1520,7 +1571,7 @@ static int evaluate_misc_instr(uint32_t opcode, } /* SMUL < x> */ - if ((opcode & 0x00600000) == 0x00300000) { + if ((opcode & 0x00600000) == 0x00600000) { uint8_t Rd, Rm, Rs; instruction->type = ARM_SMULxy; Rd = (opcode & 0xf0000) >> 16; @@ -1541,7 +1592,7 @@ static int evaluate_misc_instr(uint32_t opcode, } /* SMULW < y> */ - if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) { + if (((opcode & 0x00600000) == 0x00200000) && (x == 1)) { uint8_t Rd, Rm, Rs; instruction->type = ARM_SMULWy; Rd = (opcode & 0xf0000) >> 16; @@ -1564,6 +1615,33 @@ static int evaluate_misc_instr(uint32_t opcode, return ERROR_OK; } +static int evaluate_mov_imm(uint32_t opcode, + uint32_t address, struct arm_instruction *instruction) +{ + uint16_t immediate; + uint8_t Rd; + bool T; + + Rd = (opcode & 0xf000) >> 12; + T = opcode & 0x00400000; + immediate = (opcode & 0xf0000) >> 4 | (opcode & 0xfff); + + instruction->type = ARM_MOV; + instruction->info.data_proc.Rd = Rd; + + snprintf(instruction->text, + 128, + "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMOV%s%s r%i, #0x%" PRIx16, + address, + opcode, + T ? "T" : "W", + COND(opcode), + Rd, + immediate); + + return ERROR_OK; +} + static int evaluate_data_proc(uint32_t opcode, uint32_t address, struct arm_instruction *instruction) { @@ -1840,16 +1918,9 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, /* catch opcodes with [27:25] = b001 */ if ((opcode & 0x0e000000) == 0x02000000) { - /* Undefined instruction */ - 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); - return ERROR_OK; - } + /* 16-bit immediate load */ + if ((opcode & 0x0fb00000) == 0x03000000) + return evaluate_mov_imm(opcode, address, instruction); /* Move immediate to status register */ if ((opcode & 0x0fb00000) == 0x03200000) @@ -2898,12 +2969,27 @@ static int t2ev_b_bl(uint32_t opcode, uint32_t address, address += 4; address += offset << 1; - instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B; + char *inst; + switch ((opcode >> 12) & 0x5) { + case 0x1: + inst = "B.W"; + instruction->type = ARM_B; + break; + case 0x4: + inst = "BLX"; + instruction->type = ARM_BLX; + address &= 0xfffffffc; + break; + case 0x5: + inst = "BL"; + instruction->type = ARM_BL; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } instruction->info.b_bl_bx_blx.reg_operand = -1; instruction->info.b_bl_bx_blx.target_address = address; - sprintf(cp, "%s\t%#8.8" PRIx32, - (opcode & (1 << 14)) ? "BL" : "B.W", - address); + sprintf(cp, "%s\t%#8.8" PRIx32, inst, address); return ERROR_OK; } @@ -3080,10 +3166,9 @@ static int t2ev_b_misc(uint32_t opcode, uint32_t address, switch ((opcode >> 12) & 0x5) { case 0x1: + case 0x4: 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); @@ -3301,6 +3386,7 @@ static int t2ev_data_immed(uint32_t opcode, uint32_t address, case 0x10: case 0x12: is_signed = true; + /* fallthrough */ case 0x18: case 0x1a: /* signed/unsigned saturated add */