diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-02-16 09:10:00 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-02-16 09:10:00 +0000 |
commit | fec509d02bc933c325f1abb1ba1e16e2a3cbc2de (patch) | |
tree | ac5c50865f2868fdf787fc16c2558a72fde654b6 /rtl/arm | |
parent | 1f6cc1e53770757caf103631e0fba27c9a1f15bd (diff) | |
download | fpc-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.inc | 51 |
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 |