aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-03-06 22:33:47 +0000
committerNick Clifton <nickc@redhat.com>2001-03-06 22:33:47 +0000
commit4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5 (patch)
tree2042b5c453e962b76adfdd2eb4b67bd6899cfb55 /sim
parentf8f3c6cc3747d01156af27c7cc74a4628755f4d0 (diff)
downloadfsf-binutils-gdb-4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5.zip
fsf-binutils-gdb-4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5.tar.gz
fsf-binutils-gdb-4f3c3dbb370a8c0c8b66710c5d0c2854c1bab4f5.tar.bz2
Fix BLX(1) for Thumb
Diffstat (limited to 'sim')
-rw-r--r--sim/arm/ChangeLog6
-rw-r--r--sim/arm/thumbemu.c23
2 files changed, 24 insertions, 5 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog
index fd11ec1..d3d5b1c 100644
--- a/sim/arm/ChangeLog
+++ b/sim/arm/ChangeLog
@@ -1,3 +1,9 @@
+2001-03-06 Nick Clifton <nickc@redhat.com>
+
+ * thumbemu.c (ARMul_ThumbDecode): Delete label bo_blx2.
+ Compute destination address of BLX(1) instruction by
+ taking bit 1 from PC and not from bit 0 of the offset.
+
2001-02-27 Nick Clifton <nickc@redhat.com>
* armvirt.c (GetWord): Add new parameter - check - to enable or
diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c
index 3351c2f..4f00733 100644
--- a/sim/arm/thumbemu.c
+++ b/sim/arm/thumbemu.c
@@ -481,7 +481,6 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
}
/* Drop through. */
- do_blx2: /* BLX instruction 2 */
/* Format 19 */
/* There is no single ARM instruction equivalent for this
instruction. Also, it should only ever be matched with the
@@ -514,17 +513,31 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
|((tinstr & (1 << 10)) ? 0xFF800000 : 0));
valid = t_branch; /* in-case we don't have the 2nd half */
tinstr = next_instr; /* move the instruction down */
+ pc += 2; /* point the pc at the 2nd half */
if (((tinstr & 0xF800) >> 11) != 31)
{
if (((tinstr & 0xF800) >> 11) == 29)
{
- pc += 2;
- goto do_blx2;
+ ARMword tmp = (pc + 2);
+
+ /* Bit one of the destination address comes from bit one of the
+ address of the first (H == 10) half of the instruction, not
+ from the offset in the instruction. */
+ state->Reg[15] = ((state->Reg[14]
+ + ((tinstr & 0x07FE) << 1)
+ + ((pc - 2) & 2))
+ & 0xFFFFFFFC);
+ CLEART;
+ state->Reg[14] = (tmp | 1);
+ valid = t_branch;
+ FLUSHPIPE;
}
- break; /* exit, since not correct instruction */
+ else
+ /* Exit, since not correct instruction. */
+ pc -= 2;
+ break;
}
/* else we fall through to process the second half of the BL */
- pc += 2; /* point the pc at the 2nd half */
case 31: /* BL instruction 2 */
/* Format 19 */
/* There is no single ARM instruction equivalent for this