summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2008-08-03 15:35:32 +0000
committercognet <cognet@FreeBSD.org>2008-08-03 15:35:32 +0000
commit28def2c5ae2c4a5561bbc4ab5275aa8c916733a6 (patch)
treef32e88ed6eca88ab25d3ef5bdce4ecee48c2f2e8 /sys/arm
parent6fbc5fa75ef62cf235faaa5bd3d0e3d6f0543229 (diff)
downloadFreeBSD-src-28def2c5ae2c4a5561bbc4ab5275aa8c916733a6.zip
FreeBSD-src-28def2c5ae2c4a5561bbc4ab5275aa8c916733a6.tar.gz
Add "add pc, whatever" as a branch instruction, we use it in memcpy().
MFC after: 3 days
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/db_interface.c36
-rw-r--r--sys/arm/include/db_machdep.h5
2 files changed, 39 insertions, 2 deletions
diff --git a/sys/arm/arm/db_interface.c b/sys/arm/arm/db_interface.c
index 8076ed3..5ec9110 100644
--- a/sys/arm/arm/db_interface.c
+++ b/sys/arm/arm/db_interface.c
@@ -297,6 +297,41 @@ branch_taken(u_int insn, db_addr_t pc)
u_int addr, nregs, offset = 0;
switch ((insn >> 24) & 0xf) {
+ case 0x2: /* add pc, reg1, #value */
+ case 0x0: /* add pc, reg1, reg2, lsl #offset */
+ addr = db_fetch_reg((insn >> 16) & 0xf);
+ if (((insn >> 16) & 0xf) == 15)
+ addr += 8;
+ if (insn & 0x0200000) {
+ offset = (insn >> 7) & 0x1e;
+ offset = (insn & 0xff) << (32 - offset) |
+ (insn & 0xff) >> offset;
+ } else {
+
+ offset = db_fetch_reg(insn & 0x0f);
+ if ((insn & 0x0000ff0) != 0x00000000) {
+ if (insn & 0x10)
+ nregs = db_fetch_reg((insn >> 8) & 0xf);
+ else
+ nregs = (insn >> 7) & 0x1f;
+ switch ((insn >> 5) & 3) {
+ case 0:
+ /* lsl */
+ offset = offset << nregs;
+ break;
+ case 1:
+ /* lsr */
+ offset = offset >> nregs;
+ break;
+ default:
+ break; /* XXX */
+ }
+
+ }
+ return (addr + offset);
+
+ }
+
case 0xa: /* b ... */
case 0xb: /* bl ... */
addr = ((insn << 2) & 0x03ffffff);
@@ -311,6 +346,7 @@ branch_taken(u_int insn, db_addr_t pc)
case 0x1: /* mov pc, reg */
addr = db_fetch_reg(insn & 0xf);
return (addr);
+ case 0x4:
case 0x5: /* ldr pc, [reg] */
addr = db_fetch_reg((insn >> 16) & 0xf);
/* ldr pc, [reg, #offset] */
diff --git a/sys/arm/include/db_machdep.h b/sys/arm/include/db_machdep.h
index 0985b18..da3b30e 100644
--- a/sys/arm/include/db_machdep.h
+++ b/sys/arm/include/db_machdep.h
@@ -74,8 +74,9 @@ typedef int db_expr_t;
#define inst_branch(ins) (((ins) & 0x0f000000) == 0x0a000000 || \
((ins) & 0x0fdffff0) == 0x079ff100 || \
- ((ins) & 0x0ff0f000) == 0x0590f000 || \
- ((ins) & 0x0ffffff0) == 0x012fff30) /* blx */
+ ((ins) & 0x0cf0f000) == 0x0490f000 || \
+ ((ins) & 0x0ffffff0) == 0x012fff30 || /* blx */ \
+ ((ins) & 0x0de0f000) == 0x0080f000)
#define inst_load(ins) (0)
#define inst_store(ins) (0)
OpenPOWER on IntegriCloud