Explorar o código

+ MIPS: Assembler implementation of FillChar
* Removed commented out assembler implementations of Inclocked(longint) and Declocked(longint) and replaced them with calls to InterlockedIncrement/Decrement, so they actually do the locking.

git-svn-id: trunk@28672 -

sergei %!s(int64=11) %!d(string=hai) anos
pai
achega
b588b3143a
Modificáronse 1 ficheiros con 64 adicións e 119 borrados
  1. 64 119
      rtl/mips/mips.inc

+ 64 - 119
rtl/mips/mips.inc

@@ -204,6 +204,63 @@ function Sptr:Pointer;assembler;nostackframe;
     move $2,$sp
   end;
 
+{$ifndef FPC_SYSTEM_HAS_FILLCHAR}
+{$define FPC_SYSTEM_HAS_FILLCHAR}
+procedure FillChar(var x;count:SizeInt;value:byte);assembler;nostackframe;
+// x=$a0, count=$a1, value=$a2
+// $t0 and $t1 used as temps
+  asm
+    // correctness of this routine depends on instructions in delay slots!!
+    slti   $t1, $a1, 8
+    bne    $t1, $0, .Lless8
+    andi   $a2, 0xff
+
+    beq    $a2, $0, .L1         // if value is zero, expansion can be skipped
+    sll    $t1, $a2, 8
+    or     $a2, $t1
+    sll    $t1, $a2, 16
+    or     $a2, $t1
+.L1:
+    subu   $t1, $0, $a0         // negate
+    andi   $t1, 3               // misalignment 0..3
+    beq    $t1, $0, .L2
+    subu   $a1, $t1             // decrease count (if branching, this is no-op because $t1=0)
+{$ifdef ENDIAN_BIG}
+    swl    $a2, 0($a0)
+{$else ENDIAN_BIG}
+    swr    $a2, 0($a0)
+{$endif ENDIAN_BIG}
+    addu   $a0, $t1             // add misalignment to address, making it dword-aligned
+.L2:
+    andi   $t1, $a1, 7          // $t1=count mod 8
+    beq    $t1, $a1, .L3        // (count and 7)=count => (count and (not 7))=0
+    subu   $t0, $a1, $t1        // $t0=count div 8
+    addu   $t0, $a0             // $t0=last loop address
+    move   $a1, $t1
+.Lloop8:                        // do 2 dwords per iteration
+    addiu  $a0, 8
+    sw     $a2, -8($a0)
+    bne    $a0, $t0, .Lloop8
+    sw     $a2, -4($a0)
+.L3:
+    andi   $t1, $a1, 4          // handle a single dword separately
+    beq    $t1, $0, .Lless8
+    subu   $a1, $t1
+    sw     $a2, 0($a0)
+    addiu  $a0, 4
+
+.Lless8:
+    ble    $a1, $0, .Lexit
+    addu   $t0, $a1, $a0
+.L4:
+    addiu  $a0, 1
+    bne    $a0, $t0, .L4
+    sb     $a2, -1($a0)
+.Lexit:
+  end;
+{$endif FPC_SYSTEM_HAS_FILLCHAR}
+
+
 {$ifdef USE_MIPS_STK2_ASM}
 {$ifndef FPC_SYSTEM_HAS_MOVE}
 (* Disabled for now
@@ -411,132 +468,20 @@ procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];
   end;
 *)
 {$endif FPC_SYSTEM_HAS_MOVE}
-{****************************************************************************
-                               Integer math
-****************************************************************************}
-
-var
-  fpc_system_lock : longint; export name 'fpc_system_lock';
-
+{$endif def USE_MIPS_STK2_ASM}
 
 {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
-function declocked(var l : longint) : boolean;assembler;nostackframe;
-{ input:  address of l in $4                                      }
-{ output: boolean indicating whether l is zero after decrementing }
-asm
-  sw  $4,0($23)
-  sw  $5,-4($23)
-  sw  $6,-8($23)
-  sw  $7,-12($23)
-  sw  $8,-16($23)
-  sw  $9,-20($23)
-  sw  $10,-24($23)
-  sw  $11,-28($23)
-  sw  $12,-32($23)
-  sw  $13,-36($23)
-  sw  $14,-40($23)
-  addiu  $23,$23,-44
-
-
-
-.Ldeclocked1:
-  lui $5,%hi(fpc_system_lock)
-  addiu $5,$5,%lo(fpc_system_lock)
-  ll $6,0($5)
-  ori $7,$6,1
-  beq $7,$6,.Ldeclocked1
-  nop
-  sc  $7,0($5)
-
-  beq $7,$0,.Ldeclocked1
-  nop
-
-  lw $5,0($4)
-  addiu $5,$5,-1
-  sw $5,0($4)
-  seq $2,$5,$0
-
-
-  { unlock }
-  lui $5,%hi(fpc_system_lock)
-  addiu $5,$5,%lo(fpc_system_lock)
-  sw $0,0($5)
-
-  addiu  $23,$23,44
-  lw  $4,0($23)
-  lw  $5,-4($23)
-  lw  $6,-8($23)
-  lw  $7,-12($23)
-  lw  $8,-16($23)
-  lw  $9,-20($23)
-  lw  $10,-24($23)
-  lw  $11,-28($23)
-  lw  $12,-32($23)
-  lw  $13,-36($23)
-  lw  $14,-40($23)
+function declocked(var l: longint) : boolean; inline;
+begin
+  Result:=InterLockedDecrement(l) = 0;
 end;
 
 
 {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
-procedure inclocked(var l : longint);assembler;nostackframe;
-asm
-  { usually, we shouldn't lock here so saving the stack frame for these extra intructions is
-    worse the effort, especially while waiting :)
-  }
-
-  { unlock }
-
-  sw  $4,0($23)
-  sw  $5,-4($23)
-  sw  $6,-8($23)
-  sw  $7,-12($23)
-  sw  $8,-16($23)
-  sw  $9,-20($23)
-  sw  $10,-24($23)
-  sw  $11,-28($23)
-  sw  $12,-32($23)
-  sw  $13,-36($23)
-  sw  $14,-40($23)
-  addiu  $23,$23,-44
-
-
-.Ldeclocked1:
-  lui $5,%hi(fpc_system_lock)
-  addiu $5,$5,%lo(fpc_system_lock)
-  ll $6,0($5)
-  ori $7,$6,1
-  beq $7,$6,.Ldeclocked1
-  nop
-  sc  $7,0($5)
-
-  beq $7,$0,.Ldeclocked1
-  nop
-
-  lw $5,0($4)
-  addiu $5,$5,1
-  sw $5,0($4)
-
-
-  { unlock }
-  lui $5,%hi(fpc_system_lock)
-  addiu $5,$5,%lo(fpc_system_lock)
-  sw $0,0($5)
-
-  addiu  $23,$23,44
-  lw  $4,0($23)
-  lw  $5,-4($23)
-  lw  $6,-8($23)
-  lw  $7,-12($23)
-  lw  $8,-16($23)
-  lw  $9,-20($23)
-  lw  $10,-24($23)
-  lw  $11,-28($23)
-  lw  $12,-32($23)
-  lw  $13,-36($23)
-  lw  $14,-40($23)
-
+procedure inclocked(var l: longint); inline;
+begin
+  InterLockedIncrement(l);
 end;
-{$endif def USE_MIPS_STK2_ASM}
 
 function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
 asm