aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2007-09-25 15:21:00 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-10-12 23:43:22 +0100
commitc1f438f5eec867707022e5f33bec5e91ec12f6e7 (patch)
treecd10301fad4a855d59defcce878eee2e15e0cee5 /arch
parentec6b1482265ec8430fc38c79205567c3601d8901 (diff)
[ARM] 4581/1: Fix the conditional execution of the NWFPE instructions
Starting with ARMv7-A, conditional execution of undefined instructions can trigger an exception even if the condition check fails. This patch modifies the NWFPE support to check the condition before emulating the instruction. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/nwfpe/entry.S25
1 files changed, 14 insertions, 11 deletions
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
index 1dc13bc6d81..48bca0db460 100644
--- a/arch/arm/nwfpe/entry.S
+++ b/arch/arm/nwfpe/entry.S
@@ -70,13 +70,24 @@ floating point instructions. GCC attempts to group floating point
instructions to allow the emulator to spread the cost of the trap over
several floating point instructions. */
+#include <asm/asm-offsets.h>
+
.globl nwfpe_enter
nwfpe_enter:
mov r4, lr @ save the failure-return addresses
mov sl, sp @ we access the registers via 'sl'
- ldr r5, [sp, #60] @ get contents of PC;
+ ldr r5, [sp, #S_PC] @ get contents of PC;
+ mov r6, r0 @ save the opcode
emulate:
+ ldr r1, [sp, #S_PSR] @ fetch the PSR
+ bl checkCondition @ check the condition
+ cmp r0, #0 @ r0 = 0 ==> condition failed
+
+ @ if condition code failed to match, next insn
+ beq next @ get the next instruction;
+
+ mov r0, r6 @ prepare for EmulateAll()
bl EmulateAll @ emulate the instruction
cmp r0, #0 @ was emulation successful
moveq pc, r4 @ no, return failure
@@ -91,18 +102,10 @@ next:
teqne r2, #0x0E000000
movne pc, r9 @ return ok if not a fp insn
- str r5, [sp, #60] @ update PC copy in regs
+ str r5, [sp, #S_PC] @ update PC copy in regs
mov r0, r6 @ save a copy
- ldr r1, [sp, #64] @ fetch the condition codes
- bl checkCondition @ check the condition
- cmp r0, #0 @ r0 = 0 ==> condition failed
-
- @ if condition code failed to match, next insn
- beq next @ get the next instruction;
-
- mov r0, r6 @ prepare for EmulateAll()
- b emulate @ if r0 != 0, goto EmulateAll
+ b emulate @ check condition and emulate
@ We need to be prepared for the instructions at .Lx1 and .Lx2
@ to fault. Emit the appropriate exception gunk to fix things up.