summaryrefslogtreecommitdiff
path: root/rtl/arm
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-02-16 09:10:00 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-02-16 09:10:00 +0000
commitfec509d02bc933c325f1abb1ba1e16e2a3cbc2de (patch)
treeac5c50865f2868fdf787fc16c2558a72fde654b6 /rtl/arm
parent1f6cc1e53770757caf103631e0fba27c9a1f15bd (diff)
downloadfpc-fec509d02bc933c325f1abb1ba1e16e2a3cbc2de.tar.gz
* patch by Bernd which fixes InterLockedxxx functions on ARMv4T, resolves #25518
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@26792 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/arm')
-rw-r--r--rtl/arm/arm.inc51
1 files changed, 46 insertions, 5 deletions
diff --git a/rtl/arm/arm.inc b/rtl/arm/arm.inc
index 2f2d544a5f..b0b4b7e9cf 100644
--- a/rtl/arm/arm.inc
+++ b/rtl/arm/arm.inc
@@ -584,8 +584,16 @@ asm
sub r3, r3, #0x3F
sub r1, r0, #1 // Decrement value
+{$ifdef CPUARM_HAS_BLX}
blx r3 // Call kuser_cmpxchg, sets C-Flag on success
-
+{$else}
+ mov lr, pc
+{$ifdef CPUARM_HAS_BX}
+ bx r3
+{$else}
+ mov pc, r3
+{$endif}
+{$endif}
// MOVS sets the Z flag when the result reaches zero, this can be used later on
// The C-Flag will not be modified by this because we're not doing any shifting
movcss r0, r1 // We expect that to work most of the time so keep it pipeline friendly
@@ -675,8 +683,16 @@ asm
sub r3, r3, #0x3F
add r1, r0, #1 // Increment value
+{$ifdef CPUARM_HAS_BLX}
blx r3 // Call kuser_cmpxchg, sets C-Flag on success
-
+{$else}
+ mov lr, pc
+{$ifdef CPUARM_HAS_BX}
+ bx r3
+{$else}
+ mov pc, r3
+{$endif}
+{$endif}
movcs r0, r1 // We expect that to work most of the time so keep it pipeline friendly
ldmcsfd r13!, {pc}
b .Latomic_inc_loop // kuser_cmpxchg sets C flag on error
@@ -738,8 +754,16 @@ asm
mvn r3, #0x0000f000
sub r3, r3, #0x3F
mov r4, r0 // save the current value because kuser_cmpxchg clobbers r0
-
+{$ifdef CPUARM_HAS_BLX}
blx r3 // Call kuser_cmpxchg, sets C-Flag on success
+{$else}
+ mov lr, pc
+{$ifdef CPUARM_HAS_BX}
+ bx r3
+{$else}
+ mov pc, r3
+{$endif}
+{$endif}
// restore the original value if needed
movcs r0, r4
ldmcsfd r13!, {r4, pc}
@@ -803,7 +827,16 @@ asm
sub r3, r3, #0x3F
add r1, r0, r4 // Add to value
+{$ifdef CPUARM_HAS_BLX}
blx r3 // Call kuser_cmpxchg, sets C-Flag on success
+{$else}
+ mov lr, pc
+{$ifdef CPUARM_HAS_BX}
+ bx r3
+{$else}
+ mov pc, r3
+{$endif}
+{$endif}
// r1 does not get clobbered, so just get back the original value
// Otherwise we would have to allocate one more register and store the
// temporary value
@@ -866,8 +899,16 @@ asm
// r1 and r2 will not be clobbered by kuser_cmpxchg
// If we have to loop, r0 will be set to the original Comperand
.Linterlocked_compare_exchange_loop:
-
- blx r3 // Call kuser_cmpxchg sets C-Flag on success
+{$ifdef CPUARM_HAS_BLX}
+ blx r3 // Call kuser_cmpxchg, sets C-Flag on success
+{$else}
+ mov lr, pc
+{$ifdef CPUARM_HAS_BX}
+ bx r3
+{$else}
+ mov pc, r3
+{$endif}
+{$endif}
movcs r0, r4 // Return the previous value on success
ldmcsfd r13!, {r4, pc}
// The error case is a bit tricky, kuser_cmpxchg does not return the current value