This is the mail archive of the
gdb-prs@sources.redhat.com
mailing list for the GDB project.
sim/1283: ARM v4t LDR and LDM of pc should not change mode
- From: dmcq at tao-group dot com
- To: gdb-gnats at sources dot redhat dot com
- Date: 14 Jul 2003 13:00:57 -0000
- Subject: sim/1283: ARM v4t LDR and LDM of pc should not change mode
- Reply-to: dmcq at tao-group dot com
>Number: 1283
>Category: sim
>Synopsis: ARM v4t LDR and LDM of pc should not change mode
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Jul 14 13:08:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: dmcq@tao-group.com
>Release: GDB-5.3
>Organization:
>Environment:
I'm not actually running gdb or *nix - I'm running the ARM simulator on its own.
>Description:
In ARM v4 the LDR and LDM and the Thumb v4 POP instructions should not affect the ARM/Thumb mode. This facility was introduced in the v5 architecture (and is implemented in ARM9E but not ARM9 I believe!)
The ARM simulator currently always switches mode depending on whether the bit is set irrespective of whether it is v4 or v5.
>How-To-Repeat:
You'd need to switch the v5 switch off and run with thumb enabled to exhibit the problem. calling a routine in ARM mode with bit 0 set should then crash whereas it shouldn't on v4 (t should on v5).
>Fix:
I've attached a diff file showing how I got round the problem with changes to, the new versions are in the arm2 directory.
The diffs were with
sim/arm/armemu 1.30
sim/arm/armemu.h 1.15
in redhat src/sim/arm
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="diff.txt"
Content-Disposition: inline; filename="diff.txt"
diff -pcw arm/armemu.c arm2/armemu.c
*** arm/armemu.c Mon Jul 14 12:09:42 2003
--- arm2/armemu.c Mon Jul 14 13:42:27 2003
*************** static ARMword GetDPSRegRHS (ARM
*** 26,31 ****
--- 26,32 ----
static void WriteR15 (ARMul_State *, ARMword);
static void WriteSR15 (ARMul_State *, ARMword);
static void WriteR15Branch (ARMul_State *, ARMword);
+ static void WriteR15Load (ARMul_State *, ARMword);
static ARMword GetLSRegRHS (ARMul_State *, ARMword);
static ARMword GetLS7RHS (ARMul_State *, ARMword);
static unsigned LoadWord (ARMul_State *, ARMword, ARMword);
*************** WriteR15Branch (ARMul_State * state, ARM
*** 3914,3919 ****
--- 3915,3931 ----
#endif
}
+ /* Before ARM_v5 LDR and LDM of pc did not change mode. */
+
+ static void
+ WriteR15Load (ARMul_State * state, ARMword src)
+ {
+ if (state->is_v5)
+ WriteR15Branch (state, src);
+ else
+ WriteR15 (state, src);
+ }
+
/* This routine evaluates most Load and Store register RHS's. It is
intended to be called from the macro LSRegRHS, which filters the
common case of an unshifted register with in line code. */
*************** LoadMult (ARMul_State * state, ARMword i
*** 4426,4432 ****
if (BIT (15) && !state->Aborted)
/* PC is in the reg list. */
! WriteR15Branch (state, PC);
/* To write back the final register. */
ARMul_Icycles (state, 1, 0L);
--- 4438,4444 ----
if (BIT (15) && !state->Aborted)
/* PC is in the reg list. */
! WriteR15Load (state, PC);
/* To write back the final register. */
ARMul_Icycles (state, 1, 0L);
diff -pcw arm/armemu.h arm2/armemu.h
*** arm/armemu.h Mon Jul 14 12:10:04 2003
--- arm2/armemu.h Mon Jul 14 13:42:47 2003
*************** extern ARMword isize;
*** 403,409 ****
do \
{ \
if (DESTReg == 15) \
! WriteR15Branch (state, d); \
else \
DEST = d; \
} \
--- 403,409 ----
do \
{ \
if (DESTReg == 15) \
! WriteR15Load (state, d); \
else \
DEST = d; \
} \