mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 07:49:32 +01:00
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:
parent
963a488ca2
commit
bea46f3403
@ -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}
|
||||
|
||||
@ -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}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user