Преглед изворни кода

* Assembler Interlocked* functions for ARM.

git-svn-id: trunk@4011 -
yury пре 19 година
родитељ
комит
d7cbde6f25
1 измењених фајлова са 92 додато и 28 уклоњено
  1. 92 28
      rtl/arm/arm.inc

+ 92 - 28
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;