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 */