mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 13:38:31 +02:00
+ atomic operations for RV32
This commit is contained in:
parent
923ad699a1
commit
cd76562339
@ -15,6 +15,10 @@
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
{****************************************************************************
|
||||
stack frame related stuff
|
||||
****************************************************************************}
|
||||
|
||||
{$IFNDEF INTERNAL_BACKTRACE}
|
||||
{$define FPC_SYSTEM_HAS_GET_FRAME}
|
||||
function get_frame:pointer;assembler;nostackframe;
|
||||
@ -197,3 +201,20 @@ procedure WriteBarrier; assembler; nostackframe;
|
||||
asm
|
||||
fence ow, ow
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
atomic operations
|
||||
****************************************************************************}
|
||||
|
||||
{$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
|
||||
function declocked(var l: longint) : boolean; inline;
|
||||
begin
|
||||
Result:=InterLockedDecrement(l) = 0;
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
|
||||
procedure inclocked(var l: longint); inline;
|
||||
begin
|
||||
InterLockedIncrement(l);
|
||||
end;
|
||||
|
@ -18,6 +18,9 @@
|
||||
{ Common RiscV stuff }
|
||||
{$I ../riscv/riscv.inc}
|
||||
|
||||
{****************************************************************************
|
||||
stack frame related stuff
|
||||
****************************************************************************}
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
|
||||
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
|
||||
@ -32,47 +35,109 @@ function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
|
||||
lw a0, -4*2(a0)
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
atomic operations
|
||||
****************************************************************************}
|
||||
|
||||
|
||||
{ while some of the functions below could be shared with RiscV 64, this makes no sense imo
|
||||
to scatter those functions around }
|
||||
|
||||
{$ifdef VER3_2}
|
||||
function InterLockedDecrement (var Target: longint) : longint;
|
||||
begin
|
||||
dec(Target);
|
||||
Result:=Target;
|
||||
function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
|
||||
{$else VER3_2}
|
||||
{$define FPC_SYSTEM_HAS_ATOMIC_DEC_32}
|
||||
function fpc_atomic_dec_32 (var Target: longint) : longint; assembler; nostackframe;
|
||||
{$endif VER3_2}
|
||||
asm
|
||||
{$ifdef CPURV_HAS_ATOMIC}
|
||||
addi a1, x0, -1
|
||||
amoadd.w a0, a1, (a0)
|
||||
add a0, a0, a1
|
||||
{$else CPURV_HAS_ATOMIC}
|
||||
lw a1, 0(a0)
|
||||
addi a1, a1, -1
|
||||
sw a1, 0(a0)
|
||||
addi a0, a1, 0
|
||||
{$endif CPURV_HAS_ATOMIC}
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedIncrement (var Target: longint) : longint;
|
||||
begin
|
||||
inc(Target);
|
||||
Result:=Target;
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchange (var Target: longint;Source : longint) : longint;
|
||||
begin
|
||||
Result:=Target;
|
||||
Target:=Source;
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
|
||||
begin
|
||||
Result:=Target;
|
||||
inc(Target,Source);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
|
||||
{$ifdef VER3_2}
|
||||
function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
|
||||
function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
|
||||
{$else VER3_2}
|
||||
{$define FPC_SYSTEM_HAS_ATOMIC_INC_32}
|
||||
function fpc_atomic_inc_32 (var Target: longint) : longint; assembler; nostackframe;
|
||||
{$endif VER3_2}
|
||||
asm
|
||||
{$ifdef CPURV_HAS_ATOMIC}
|
||||
addi a1, x0, 1
|
||||
amoadd.w a0, a1, (a0)
|
||||
add a0, a0, a1
|
||||
{$else CPURV_HAS_ATOMIC}
|
||||
lw a1, 0(a0)
|
||||
addi a1, a1, 1
|
||||
sw a1, 0(a0)
|
||||
addi a0, a1, 0
|
||||
{$endif CPURV_HAS_ATOMIC}
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef VER3_2}
|
||||
function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
|
||||
{$else VER3_2}
|
||||
{$define FPC_SYSTEM_HAS_ATOMIC_XCHG_32}
|
||||
function fpc_atomic_xchg_32 (var Target: longint;Source : longint) : longint; assembler; nostackframe;
|
||||
{$endif VER3_2}
|
||||
asm
|
||||
{$ifdef CPURV_HAS_ATOMIC}
|
||||
amoswap.w a0, a1, (a0)
|
||||
{$else CPURV_HAS_ATOMIC}
|
||||
lw a2, 0(a0)
|
||||
sw a1, 0(a0)
|
||||
addi a0, a2, 0
|
||||
{$endif CPURV_HAS_ATOMIC}
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef VER3_2}
|
||||
function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler; nostackframe;
|
||||
{$else VER3_2}
|
||||
{$define FPC_SYSTEM_HAS_ATOMIC_CMP_XCHG_32}
|
||||
function fpc_atomic_cmp_xchg_32 (var Target: longint; NewValue: longint; Comparand: longint) : longint; [public,alias:'FPC_ATOMIC_CMP_XCHG_32'];
|
||||
function fpc_atomic_cmp_xchg_32 (var Target: longint; NewValue: longint; Comparand: longint) : longint; [public,alias:'FPC_ATOMIC_CMP_XCHG_32']; assembler; nostackframe;
|
||||
{$endif VER3_2}
|
||||
begin
|
||||
Result:=Target;
|
||||
if Target={$ifdef VER3_2}Comperand{$else}Comparand{$endif} then
|
||||
Target:=NewValue;
|
||||
asm
|
||||
{$ifdef CPURV_HAS_ATOMIC}
|
||||
.LLoop:
|
||||
lr.w a3, 0(a0)
|
||||
bne a3, a2, .LFail
|
||||
sc.w a4, a1, 0(a0)
|
||||
bne a4, x0, .LLoop
|
||||
.LFail:
|
||||
addi a0, a3, 0
|
||||
{$else CPURV_HAS_ATOMIC}
|
||||
lw a3, 0(a0)
|
||||
bne a3, a2, .LFail
|
||||
sw a1, 0(a0)
|
||||
.LFail:
|
||||
addi a0, a3, 0
|
||||
{$endif CPURV_HAS_ATOMIC}
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef VER3_2}
|
||||
function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe;
|
||||
{$else VER3_2}
|
||||
{$define FPC_SYSTEM_HAS_ATOMIC_ADD_32}
|
||||
function fpc_atomic_add_32 (var Target: longint;Value: longint) : longint; assembler; nostackframe;
|
||||
{$endif VER3_2}
|
||||
asm
|
||||
{$ifdef CPURV_HAS_ATOMIC}
|
||||
amoadd.w a0, a1, (a0)
|
||||
{$else CPURV_HAS_ATOMIC}
|
||||
lw a2, 0(a0)
|
||||
add a2, a2, a1
|
||||
sw a2, 0(a0)
|
||||
addi a0, a2, 0
|
||||
{$endif CPURV_HAS_ATOMIC}
|
||||
end;
|
||||
|
@ -18,6 +18,10 @@
|
||||
{ Common RiscV stuff }
|
||||
{$I ../riscv/riscv.inc}
|
||||
|
||||
{****************************************************************************
|
||||
stack frame related stuff
|
||||
****************************************************************************}
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
|
||||
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
|
||||
asm
|
||||
@ -32,7 +36,7 @@ function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
stack frame related stuff
|
||||
atomic operations
|
||||
****************************************************************************}
|
||||
|
||||
{$ifdef VER3_2}
|
||||
@ -235,20 +239,6 @@ function fpc_atomic_add_64 (var Target: int64;Value : int64) : int64; assembler;
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
|
||||
function declocked(var l: longint) : boolean; inline;
|
||||
begin
|
||||
Result:=InterLockedDecrement(l) = 0;
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
|
||||
procedure inclocked(var l: longint); inline;
|
||||
begin
|
||||
InterLockedIncrement(l);
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_DECLOCKED_INT64}
|
||||
function declocked(var l:int64):boolean;
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user