target/arm: Add PLD command to ARM disassembler.
Updates the ARM disassembler to handle PLD (PreLoad Data) commands. Previously handled by printing a TODO message. There are three forms of the command: literal, register, and immediate. Simply decode based off of the A1 encoding for the instructions in the ARM ARM. Also fixes mask to handle PLDW commands. Change-Id: I63bf97f16af254e838462c7cfac80f6c4681c556 Signed-off-by: James Marshall <jcmarsh@gwmail.gwu.edu> Reviewed-on: http://openocd.zylin.com/4348 Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
This commit is contained in:
parent
548bcee30d
commit
a0356398e5
|
@ -118,15 +118,78 @@ static int evaluate_pld(uint32_t opcode,
|
||||||
uint32_t address, struct arm_instruction *instruction)
|
uint32_t address, struct arm_instruction *instruction)
|
||||||
{
|
{
|
||||||
/* PLD */
|
/* PLD */
|
||||||
if ((opcode & 0x0d70f000) == 0x0550f000) {
|
if ((opcode & 0x0d30f000) == 0x0510f000) {
|
||||||
|
uint8_t Rn;
|
||||||
|
uint8_t U;
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
instruction->type = ARM_PLD;
|
instruction->type = ARM_PLD;
|
||||||
|
Rn = (opcode & 0xf0000) >> 16;
|
||||||
|
U = (opcode & 0x00800000) >> 23;
|
||||||
|
if (Rn == 0xf) {
|
||||||
|
/* literal */
|
||||||
|
offset = opcode & 0x0fff;
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD %s%d",
|
||||||
|
address, opcode, U ? "" : "-", offset);
|
||||||
|
} else {
|
||||||
|
uint8_t I, R;
|
||||||
|
|
||||||
snprintf(instruction->text,
|
I = (opcode & 0x02000000) >> 25;
|
||||||
128,
|
R = (opcode & 0x00400000) >> 22;
|
||||||
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...",
|
|
||||||
address,
|
|
||||||
opcode);
|
|
||||||
|
|
||||||
|
if (I) {
|
||||||
|
/* register PLD{W} [<Rn>,+/-<Rm>{, <shift>}] */
|
||||||
|
offset = (opcode & 0x0F80) >> 7;
|
||||||
|
uint8_t Rm;
|
||||||
|
Rm = opcode & 0xf;
|
||||||
|
|
||||||
|
if (offset == 0) {
|
||||||
|
/* No shift */
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d]",
|
||||||
|
address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
uint8_t shift;
|
||||||
|
shift = (opcode & 0x60) >> 5;
|
||||||
|
|
||||||
|
if (shift == 0x0) {
|
||||||
|
/* LSL */
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, LSL #0x%x)",
|
||||||
|
address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
|
||||||
|
} else if (shift == 0x1) {
|
||||||
|
/* LSR */
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, LSR #0x%x)",
|
||||||
|
address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
|
||||||
|
} else if (shift == 0x2) {
|
||||||
|
/* ASR */
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, ASR #0x%x)",
|
||||||
|
address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
|
||||||
|
} else if (shift == 0x3) {
|
||||||
|
/* ROR */
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, ROR #0x%x)",
|
||||||
|
address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* immediate PLD{W} [<Rn>, #+/-<imm12>] */
|
||||||
|
offset = opcode & 0x0fff;
|
||||||
|
if (offset == 0) {
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d]",
|
||||||
|
address, opcode, R ? "" : "W", Rn);
|
||||||
|
} else {
|
||||||
|
snprintf(instruction->text, 128,
|
||||||
|
"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, #%s%d]",
|
||||||
|
address, opcode, R ? "" : "W", Rn, U ? "" : "-", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
/* DSB */
|
/* DSB */
|
||||||
|
|
Loading…
Reference in New Issue