summaryrefslogtreecommitdiff
path: root/rtl/mips
diff options
context:
space:
mode:
authorsergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-09-15 19:41:34 +0000
committersergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-09-15 19:41:34 +0000
commit7c89e0ca2272f6e9724e994d17a0752fffec0251 (patch)
tree9b892808f3afdf8f174ad64dd58fd7f6a0c768fb /rtl/mips
parent3a71ec0858e29d3229ab4e1427601192f33fc17c (diff)
downloadfpc-7c89e0ca2272f6e9724e994d17a0752fffec0251.tar.gz
+ 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: http://svn.freepascal.org/svn/fpc/trunk@28672 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/mips')
-rw-r--r--rtl/mips/mips.inc183
1 files changed, 64 insertions, 119 deletions
diff --git a/rtl/mips/mips.inc b/rtl/mips/mips.inc
index 0ff662aca6..e215f6b63a 100644
--- a/rtl/mips/mips.inc
+++ b/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