aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authorJames Marshall <jcmarsh@gwmail.gwu.edu>2018-01-16 21:08:16 -0500
committerMatthias Welwarsky <matthias@welwarsky.de>2018-06-22 07:42:27 +0100
commita0356398e54984d292f4e6812cd67a9874b62f0d (patch)
treef6e093419230fb6facf1efefb24513c721cc2b7c /src/target
parent548bcee30dcfec3174e563e53ffb1559104b8a97 (diff)
downloadriscv-openocd-a0356398e54984d292f4e6812cd67a9874b62f0d.zip
riscv-openocd-a0356398e54984d292f4e6812cd67a9874b62f0d.tar.gz
riscv-openocd-a0356398e54984d292f4e6812cd67a9874b62f0d.tar.bz2
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>
Diffstat (limited to 'src/target')
-rw-r--r--src/target/arm_disassembler.c75
1 files changed, 69 insertions, 6 deletions
diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c
index 17948d6..8eb8194 100644
--- a/src/target/arm_disassembler.c
+++ b/src/target/arm_disassembler.c
@@ -118,15 +118,78 @@ static int evaluate_pld(uint32_t opcode,
uint32_t address, struct arm_instruction *instruction)
{
/* PLD */
- if ((opcode & 0x0d70f000) == 0x0550f000) {
+ if ((opcode & 0x0d30f000) == 0x0510f000) {
+ uint8_t Rn;
+ uint8_t U;
+ unsigned offset;
+
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,
- 128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...",
- address,
- opcode);
+ I = (opcode & 0x02000000) >> 25;
+ R = (opcode & 0x00400000) >> 22;
+
+ 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;
}
/* DSB */