diff options
author | yury <yury@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2006-06-30 15:36:49 +0000 |
---|---|---|
committer | yury <yury@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2006-06-30 15:36:49 +0000 |
commit | d8ef0df89b78ebd0cf34ae7c92ce5a6c037235b8 (patch) | |
tree | 0e639083d6fe28c867f08deb785c0f58a023063c | |
parent | 9940412a2ae2beb2fd63f197d8f5ecd429839c5a (diff) | |
download | fpc-d8ef0df89b78ebd0cf34ae7c92ce5a6c037235b8.tar.gz |
* Assembler Interlocked* functions for ARM.
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@4011 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | rtl/arm/arm.inc | 120 |
1 files changed, 92 insertions, 28 deletions
diff --git a/rtl/arm/arm.inc b/rtl/arm/arm.inc index 2dd8cbb613..0ecb5e8b22 100644 --- a/rtl/arm/arm.inc +++ b/rtl/arm/arm.inc @@ -182,39 +182,103 @@ asm end; *) +var + fpc_system_lock: longint; export name 'fpc_system_lock'; -{ the ARM doesn't know multiprocessor system which would require locking } +function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe; +asm +// lock + ldr r3, .Lfpc_system_lock + mov r1, #1 +.Lloop: + swp r2, r1, [r3] + cmp r2, #0 + bne .Lloop +// do the job + ldr r1, [r0] + sub r1, r1, #1 + str r1, [r0] + mov r0, r1 +// unlock and return + str r2, [r3] + mov pc, lr + +.Lfpc_system_lock: + .long fpc_system_lock +end; -function InterLockedDecrement (var Target: longint) : longint; - begin - dec(Target); - result:=target; - end; +function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe; +asm +// lock + ldr r3, .Lfpc_system_lock + mov r1, #1 +.Lloop: + swp r2, r1, [r3] + cmp r2, #0 + bne .Lloop +// do the job + ldr r1, [r0] + add r1, r1, #1 + str r1, [r0] + mov r0, r1 +// unlock and return + str r2, [r3] + mov pc, lr + +.Lfpc_system_lock: + .long fpc_system_lock +end; -function InterLockedIncrement (var Target: longint) : longint; - begin - inc(Target); - result:=target; - end; +function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe; +asm + swp r0, r1, [r0] +end; -function InterLockedExchange (var Target: longint;Source : longint) : longint; - begin - Result:=Target; - Target:=Source; - end; +function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe; +asm +// lock + ldr r3, .Lfpc_system_lock + mov r2, #1 +.Lloop: + swp r2, r2, [r3] + cmp r2, #0 + bne .Lloop +// do the job + ldr r2, [r0] + add r1, r1, r2 + str r1, [r0] + mov r0, r2 +// unlock and return + mov r2, #0 + str r2, [r3] + mov pc, lr + +.Lfpc_system_lock: + .long fpc_system_lock +end; -function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; - begin - Result:=Target; - inc(Target,Source); - end; - -function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; - begin - Result:=Target; //return initial value - if (Target=Comperand) - then Target:=NewValue; - end; +function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler; nostackframe; +asm +// lock + ldr r12, .Lfpc_system_lock + mov r3, #1 +.Lloop: + swp r3, r3, [r12] + cmp r3, #0 + bne .Lloop +// do the job + ldr r3, [r0] + cmp r3, r2 + streq r1, [r0] + mov r0, r3 +// unlock and return + mov r3, #0 + str r3, [r12] + mov pc, lr + +.Lfpc_system_lock: + .long fpc_system_lock +end; |