MIPS RTL:

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

git-svn-id: trunk@25049 -
This commit is contained in:
sergei 2013-07-05 14:03:18 +00:00
parent 963a488ca2
commit bea46f3403
2 changed files with 101 additions and 29 deletions

View File

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

View File

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