Browse Source

MIPS RTL:
* Fixed InterlockedXXX routines, hopefully thread-safe now.
+ SarInt64 assembler implementations for both mips and mipsel.

git-svn-id: trunk@25049 -

sergei 12 years ago
parent
commit
bea46f3403
2 changed files with 101 additions and 29 deletions
  1. 71 28
      rtl/mips/mips.inc
  2. 30 1
      rtl/mipsel/mips.inc

+ 71 - 28
rtl/mips/mips.inc

@@ -542,54 +542,97 @@ end;
 
 function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
 asm
-  {$warning FIXME: This implementation of InterLockedDecrement in not yet ThreadSafe }
-  // must return value after decrement
-  lw  $v0,($a0)
-  addi $v0,$v0,-1
-  sw  $v0,($a0)
+  sync
+.L1:
+  ll    $v0,($a0)
+  addiu $v1,$v0,-1
+  move  $v0,$v1        // must return value after decrement
+  sc    $v1,($a0)
+  beq   $v1,$0,.L1
+  nop
+  sync
 end;
 
 
 function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
 asm
-  {$warning FIXME: This implementation of InterLockedIncrement in not yet ThreadSafe }
-  // must return value after increment
-  lw  $v0,($a0)
-  addi $v0,$v0,1
-  sw  $v0,($a0)
+  sync
+.L1:
+  ll    $v0,($a0)
+  addiu $v1,$v0,1
+  move  $v0,$v1         // must return value after increment
+  sc    $v1,($a0)
+  beq   $v1,$0,.L1
+  nop
+  sync
 end;
 
 
 function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
 asm
-  {$warning FIXME: This implementation of InterLockedExchange in not yet ThreadSafe }
-  lw  $v0,($a0)
-  sw  $a1,($a0)
+  sync
+.L1:
+  ll    $v0,($a0)
+  move  $v1,$a1
+  sc    $v1,($a0)
+  beq   $v1,$0,.L1
+  nop
+  sync
 end;
 
 function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe;
 asm
-  {$warning FIXME: This implementation of InterLockedExchangeAdd in not yet ThreadSafe }
-  lw  $v0,($a0)
-  add $a1,$v0,$a1
-  sw  $a1,($a0)
+  sync
+.L1:
+  ll    $v0,($a0)
+  addu  $v1,$v0,$a1
+  sc    $v1,($a0)
+  beq   $v1,$0,.L1
+  nop
+  sync
 end;
 
 
 function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler; nostackframe;
 asm
-  {$warning FIXME: This implementation of InterLockedCompareAdd in not yet ThreadSafe }
-  { put old value of Target into $v0, result register }
-  lw  $v0,($a0)
-  { copy to t0 register }
-  move  $t0,$v0
-  move $v1,$a2
-  xor  $t0,$t0,$v1
-  beq  $t0,$zero,.L1
-  b    .L2
+  sync
 .L1:
-  {store NewValue (in $a1) into Target in ($(a0)) }
-  sw    $a1,($a0)
+  ll    $v0,($a0)
+  bne   $v0,$a2,.L2
+  nop
+  move  $v1,$a1
+  sc    $v1,($a0)
+  beq   $v1,$0,.L1
+  nop
+  sync
 .L2:
 end;
 
+
+{$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
+{$ifdef ENDIAN_BIG}
+{$define FPC_SYSTEM_HAS_SAR_QWORD}
+function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
+asm
+{ $a0=high(AValue) $a1=low(AValue), result: $v0:$v1 }
+    andi   $a2,$a2,63
+    sltiu  $t0,$a2,32
+    beq    $t0,$0,.L1
+    nop
+
+    srlv   $v1,$a1,$a2
+    srav   $v0,$a0,$a2
+    beq    $a2,$0,.Lexit
+    nop
+    subu   $t0,$0,$a2
+    sllv   $t0,$a0,$t0
+    or     $v1,$v1,$t0
+    b      .Lexit
+    nop
+.L1:
+    sra    $v0,$a0,31
+    srav   $v1,$a0,$a2
+.Lexit:
+end;
+{$endif ENDIAN_BIG}
+{$endif FPC_SYSTEM_HAS_SAR_QWORD}

+ 30 - 1
rtl/mipsel/mips.inc

@@ -1 +1,30 @@
-{$i ../mips/mips.inc}
+{$i ../mips/mips.inc}
+
+{$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
+{$ifdef ENDIAN_LITTLE}
+{$define FPC_SYSTEM_HAS_SAR_QWORD}
+function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
+asm
+{ $a1=high(AValue),$a0=low(AValue), result: $v1:$v0 }
+    andi   $a2,$a2,63
+    sltiu  $t0,$a2,32
+    beq    $t0,$0,.L1
+    nop
+
+    srlv   $v0,$a0,$a2
+    srav   $v1,$a1,$a2
+    beq    $a2,$0,.Lexit
+    nop
+    subu   $t0,$0,$a2
+    sllv   $t0,$a1,$t0
+    or     $v0,$v0,$t0
+    b      .Lexit
+    nop
+.L1:
+    sra    $v1,$a1,31
+    srav   $v0,$a1,$a2
+.Lexit:
+end;
+{$endif ENDIAN_LITTLE}
+{$endif FPC_SYSTEM_HAS_SAR_QWORD}
+