+ 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 -
This commit is contained in:
sergei 2014-09-15 19:41:34 +00:00
parent 203089fe1a
commit b588b3143a

View File

@ -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