mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-01 23:09:32 +01:00
+ SPARC64 specific system unit code, derived from SPARC32, needs still to be adapted
git-svn-id: trunk@36433 -
This commit is contained in:
parent
4036ecb5b5
commit
053124f78a
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9956,6 +9956,7 @@ rtl/sparc64/int64p.inc svneol=native#text/plain
|
||||
rtl/sparc64/makefile.cpu svneol=native#text/plain
|
||||
rtl/sparc64/math.inc svneol=native#text/plain
|
||||
rtl/sparc64/set.inc svneol=native#text/plain
|
||||
rtl/sparc64/sparc64.inc svneol=native#text/plain
|
||||
rtl/symbian/Makefile svneol=native#text/plain
|
||||
rtl/symbian/Makefile.fpc svneol=native#text/plain
|
||||
rtl/symbian/bindings/pbeexe.cpp -text
|
||||
|
||||
970
rtl/sparc64/sparc64.inc
Normal file
970
rtl/sparc64/sparc64.inc
Normal file
@ -0,0 +1,970 @@
|
||||
{
|
||||
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 2002-2004 by the Free Pascal development team.
|
||||
|
||||
Processor dependent implementation for the system unit for
|
||||
Sparc
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
SPARC specific stuff
|
||||
****************************************************************************}
|
||||
function get_fsr : dword;assembler;[public, alias: 'FPC_GETFSR'];
|
||||
var
|
||||
fsr : dword;
|
||||
asm
|
||||
st %fsr,fsr
|
||||
ld fsr,%l0
|
||||
st %l0,__result
|
||||
end;
|
||||
|
||||
|
||||
procedure set_fsr(fsr : dword);assembler;[public, alias: 'FPC_SETFSR'];
|
||||
var
|
||||
_fsr : dword;
|
||||
asm
|
||||
// force memory location
|
||||
st fsr,_fsr
|
||||
ld _fsr,%fsr
|
||||
end;
|
||||
|
||||
|
||||
function get_got : pointer;assembler;nostackframe;[public, alias: 'FPC_GETGOT'];
|
||||
asm
|
||||
retl
|
||||
add %o7,%l7,%l7
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_SYSINITFPU}
|
||||
Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
begin
|
||||
{ enable div by 0 and invalid operation fpu exceptions
|
||||
round towards zero; ieee compliant arithmetics }
|
||||
set_fsr((get_fsr and $3fbfffff) or $09000000);
|
||||
end;
|
||||
|
||||
{$define FPC_SYSTEM_HAS_SYSRESETFPU}
|
||||
Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
procedure fpc_cpuinit;
|
||||
begin
|
||||
SysResetFPU;
|
||||
if not(IsLibrary) then
|
||||
SysInitFPU;
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_FRAME}
|
||||
function get_frame:pointer;assembler;nostackframe;
|
||||
asm
|
||||
mov %fp,%o0
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
|
||||
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
|
||||
asm
|
||||
{ framebp = %o0 }
|
||||
subcc %o0,0,%o0
|
||||
be .Lframezero
|
||||
nop
|
||||
{ flush register windows, so they are stored in the stack }
|
||||
ta 3
|
||||
ld [%o0+60],%o0
|
||||
{ check if new %o0 register is zero }
|
||||
subcc %o0,0,%o0
|
||||
be .Lframezero
|
||||
nop
|
||||
{ if not zero, add 8 to skip jmpl and delay slot }
|
||||
add %o0,8,%o0
|
||||
.Lframezero:
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
|
||||
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe;
|
||||
asm
|
||||
{ framebp = %o0 }
|
||||
subcc %o0,0,%o0
|
||||
be .Lframezero
|
||||
nop
|
||||
{ flush register windows, so they are stored in the stack }
|
||||
ta 3
|
||||
ld [%o0+56],%o0
|
||||
.Lframezero:
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_SPTR}
|
||||
function Sptr:Pointer;assembler;nostackframe;
|
||||
asm
|
||||
mov %sp,%o0
|
||||
end;
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOVE}
|
||||
{$define FPC_SYSTEM_HAS_MOVE}
|
||||
procedure Move(const source;var dest;count:{$ifdef MOVE_HAS_SIZEUINT_COUNT}SizeUInt{$else}SizeInt{$endif});[public, alias: 'FPC_MOVE'];assembler;
|
||||
{
|
||||
Registers:
|
||||
%l0 temp. to do copying
|
||||
%l1 inc/decrement
|
||||
%l2/l3/l4/l5 qword move
|
||||
}
|
||||
asm
|
||||
// count < 0 ?
|
||||
cmp %g0,%i2
|
||||
bge .Lmoveexit
|
||||
nop
|
||||
|
||||
// possible overlap?
|
||||
cmp %i0,%i1
|
||||
bcc .Lnopossibleoverlap
|
||||
nop
|
||||
// source < dest ....
|
||||
add %i0,%i2,%l0
|
||||
// overlap?
|
||||
cmp %l0,%i1
|
||||
// source+count < dest ?
|
||||
bcs .Lnopossibleoverlap
|
||||
nop
|
||||
|
||||
.Lcopybackward:
|
||||
// check alignment of source and dest
|
||||
or %i0,%i1,%l0
|
||||
|
||||
// move src and dest to the end of the blocks
|
||||
// assuming 16 byte block size
|
||||
sub %i2,1,%l1
|
||||
add %i0,%l1,%i0
|
||||
add %i1,%l1,%i1
|
||||
{
|
||||
// everything 16 byte aligned ?
|
||||
andcc %l0,15,%l0
|
||||
be .Lmovetwordwise
|
||||
// load direction in delay slot
|
||||
mov -16,%l1
|
||||
|
||||
// adjust according to block size
|
||||
add %i0,8,%i0
|
||||
add %i1,8,%i1
|
||||
andcc %l0,7,%l0
|
||||
be .Lmoveqwordwise
|
||||
mov -8,%l1
|
||||
|
||||
// adjust according to block size
|
||||
add %i0,4,%i0
|
||||
add %i1,4,%i1
|
||||
andcc %l0,3,%l0
|
||||
be .Lmovedwordwise
|
||||
mov -4,%l1
|
||||
|
||||
// adjust according to block size
|
||||
add %i0,2,%i0
|
||||
add %i1,2,%i1
|
||||
andcc %l0,1,%l0
|
||||
be .Lmovewordwise
|
||||
mov -2,%l1
|
||||
|
||||
// adjust according to block size
|
||||
add %i0,1,%i0
|
||||
add %i1,1,%i1
|
||||
}
|
||||
ba .Lmovebytewise
|
||||
mov -1,%l1
|
||||
|
||||
.Lnopossibleoverlap:
|
||||
// check alignment of source and dest
|
||||
or %i0,%i1,%l0
|
||||
|
||||
// everything 16 byte aligned ?
|
||||
andcc %l0,15,%l0
|
||||
be .Lmovetwordwise
|
||||
// load direction in delay slot
|
||||
mov 16,%l1
|
||||
andcc %l0,7,%l0
|
||||
be .Lmoveqwordwise
|
||||
mov 8,%l1
|
||||
andcc %l0,3,%l0
|
||||
be .Lmovedwordwise
|
||||
mov 4,%l1
|
||||
andcc %l0,1,%l0
|
||||
be .Lmovewordwise
|
||||
mov 2,%l1
|
||||
ba .Lmovebytewise
|
||||
mov 1,%l1
|
||||
|
||||
.Lmovetwordwise:
|
||||
srl %i2,4,%l6
|
||||
cmp %g0,%l6
|
||||
sll %l6,4,%l7
|
||||
be .Lmoveqwordwise_shift
|
||||
nop
|
||||
|
||||
.Lmovetwordwise_loop:
|
||||
ld [%i0],%l2
|
||||
ld [%i0+4],%l3
|
||||
subcc %l6,1,%l6
|
||||
ld [%i0+8],%l4
|
||||
ld [%i0+12],%l5
|
||||
add %i0,%l1,%i0
|
||||
st %l2,[%i1]
|
||||
st %l3,[%i1+4]
|
||||
st %l4,[%i1+8]
|
||||
st %l5,[%i1+12]
|
||||
add %i1,%l1,%i1
|
||||
bne .Lmovetwordwise_loop
|
||||
nop
|
||||
subcc %i2,%l7,%i2
|
||||
be .Lmoveexit
|
||||
nop
|
||||
|
||||
.Lmoveqwordwise_shift:
|
||||
sra %l1,1,%l1
|
||||
.Lmoveqwordwise:
|
||||
srl %i2,3,%l6
|
||||
cmp %g0,%l6
|
||||
sll %l6,3,%l7
|
||||
be .Lmovedwordwise_shift
|
||||
nop
|
||||
|
||||
.Lmoveqwordwise_loop:
|
||||
ld [%i0],%l2
|
||||
ld [%i0+4],%l3
|
||||
subcc %l6,1,%l6
|
||||
add %i0,%l1,%i0
|
||||
st %l2,[%i1]
|
||||
st %l3,[%i1+4]
|
||||
add %i1,%l1,%i1
|
||||
bne .Lmoveqwordwise_loop
|
||||
nop
|
||||
subcc %i2,%l7,%i2
|
||||
be .Lmoveexit
|
||||
nop
|
||||
|
||||
.Lmovedwordwise_shift:
|
||||
sra %l1,1,%l1
|
||||
.Lmovedwordwise:
|
||||
srl %i2,2,%l6
|
||||
cmp %g0,%l6
|
||||
sll %l6,2,%l7
|
||||
be .Lmovewordwise_shift
|
||||
nop
|
||||
|
||||
.Lmovedwordwise_loop:
|
||||
ld [%i0],%l0
|
||||
subcc %l6,1,%l6
|
||||
add %i0,%l1,%i0
|
||||
st %l0,[%i1]
|
||||
add %i1,%l1,%i1
|
||||
bne .Lmovedwordwise_loop
|
||||
nop
|
||||
subcc %i2,%l7,%i2
|
||||
be .Lmoveexit
|
||||
nop
|
||||
|
||||
.Lmovewordwise_shift:
|
||||
sra %l1,1,%l1
|
||||
.Lmovewordwise:
|
||||
srl %i2,1,%l6
|
||||
cmp %g0,%l6
|
||||
sll %l6,1,%l7
|
||||
be .Lmovebytewise_shift
|
||||
nop
|
||||
|
||||
.Lmovewordwise_loop:
|
||||
lduh [%i0],%l0
|
||||
subcc %l6,1,%l6
|
||||
add %i0,%l1,%i0
|
||||
sth %l0,[%i1]
|
||||
add %i1,%l1,%i1
|
||||
bne .Lmovewordwise_loop
|
||||
nop
|
||||
subcc %i2,%l7,%i2
|
||||
be .Lmoveexit
|
||||
nop
|
||||
|
||||
.Lmovebytewise_shift:
|
||||
sra %l1,1,%l1
|
||||
.Lmovebytewise:
|
||||
cmp %g0,%i2
|
||||
be .Lmoveexit
|
||||
nop
|
||||
|
||||
ldub [%i0],%l0
|
||||
subcc %i2,1,%i2
|
||||
add %i0,%l1,%i0
|
||||
stb %l0,[%i1]
|
||||
add %i1,%l1,%i1
|
||||
bne .Lmovebytewise
|
||||
nop
|
||||
.Lmoveexit:
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_MOVE}
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Integer math
|
||||
****************************************************************************}
|
||||
|
||||
var
|
||||
fpc_system_lock : byte;export name 'fpc_system_lock';
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
|
||||
function declocked(var l : longint) : boolean;assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.Ldeclocked1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .Ldeclocked1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
sub %g1,1,%g1
|
||||
st %g1,[%i0]
|
||||
|
||||
subcc %g1,1,%g0
|
||||
addx %g0,%g0,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
sub %g1,1,%g1
|
||||
st %g1,[%o0]
|
||||
|
||||
subcc %g1,1,%g0
|
||||
addx %g0,%g0,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
|
||||
procedure inclocked(var l : longint);assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.Linclocked1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .Linclocked1
|
||||
nop
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
add %g1,1,%g1
|
||||
st %g1,[%i0]
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
add %g1,1,%g1
|
||||
st %g1,[%o0]
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedDecrement (var Target: longint) : longint; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedDecrement1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedDecrement1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
sub %g1,1,%g1
|
||||
st %g1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
sub %g1,1,%g1
|
||||
st %g1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
function InterLockedIncrement (var Target: longint) : longint; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedIncrement1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedIncrement1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
add %g1,1,%g1
|
||||
st %g1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
add %g1,1,%g1
|
||||
st %g1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedExchange1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedExchange1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
st %i1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
st %o1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedExchangeAdd1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedExchangeAdd1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
add %g1,%i1,%i1
|
||||
st %i1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
add %g1,%o1,%o1
|
||||
st %o1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{ input: address of target in o0, newvalue in o1, comparand in o2 }
|
||||
{ output: value stored in target before entry of the function }
|
||||
{ side-effect: NewValue stored in target if (target = comparand) }
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterlockedCompareExchange1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterlockedCompareExchange1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
cmp %g1,%i2
|
||||
bne .LInterlockedCompareExchange2
|
||||
nop
|
||||
st %i1,[%i0]
|
||||
.LInterlockedCompareExchange2:
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
cmp %g1,%o2
|
||||
bne .LInterlockedCompareExchange2
|
||||
nop
|
||||
st %o1,[%o0]
|
||||
.LInterlockedCompareExchange2:
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
function InterLockedDecrement64(var Target: Int64) : Int64; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedDecrement1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedDecrement1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
sub %g1,1,%g1
|
||||
st %g1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
sub %g1,1,%g1
|
||||
st %g1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
function InterLockedIncrement64(var Target: Int64) : Int64; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedIncrement1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedIncrement1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
add %g1,1,%g1
|
||||
st %g1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
add %g1,1,%g1
|
||||
st %g1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchange64(var Target: Int64;Source : Int64) : Int64; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedExchange1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedExchange1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
st %i1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
st %o1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterLockedExchangeAdd64(var Target: Int64;Source : Int64) : Int64; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterLockedExchangeAdd1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterLockedExchangeAdd1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
add %g1,%i1,%i1
|
||||
st %i1,[%i0]
|
||||
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
add %g1,%o1,%o1
|
||||
st %o1,[%o0]
|
||||
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
|
||||
function InterlockedCompareExchange64(var Target: Int64; NewValue: Int64; Comperand: Int64): Int64; assembler;
|
||||
{$ifndef FPC_PIC}nostackframe;{$endif}
|
||||
asm
|
||||
{ usually, we shouldn't lock here so saving the stack frame for these extra intructions is
|
||||
worse the effort, especially while waiting :)
|
||||
}
|
||||
{ input: address of target in o0, newvalue in o1, comparand in o2 }
|
||||
{ output: value stored in target before entry of the function }
|
||||
{ side-effect: NewValue stored in target if (target = comparand) }
|
||||
{$ifdef FPC_PIC}
|
||||
sethi %hi(_GLOBAL_OFFSET_TABLE_ -8),%l7
|
||||
or %l7,%lo(_GLOBAL_OFFSET_TABLE_ -4),%l7
|
||||
call get_got
|
||||
nop
|
||||
{$endif FPC_PIC}
|
||||
.LInterlockedCompareExchange1:
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
ldstub [%g1],%g1
|
||||
cmp %g1,0
|
||||
bne .LInterlockedCompareExchange1
|
||||
nop
|
||||
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%i0],%g1
|
||||
cmp %g1,%i2
|
||||
bne .LInterlockedCompareExchange2
|
||||
nop
|
||||
st %i1,[%i0]
|
||||
.LInterlockedCompareExchange2:
|
||||
mov %g1,%i0
|
||||
{$else not FPC_PIC}
|
||||
ld [%o0],%g1
|
||||
cmp %g1,%o2
|
||||
bne .LInterlockedCompareExchange2
|
||||
nop
|
||||
st %o1,[%o0]
|
||||
.LInterlockedCompareExchange2:
|
||||
mov %g1,%o0
|
||||
{$endif FPC_PIC}
|
||||
|
||||
{ unlock }
|
||||
sethi %hi(fpc_system_lock), %g1
|
||||
or %g1,%lo(fpc_system_lock), %g1
|
||||
{$ifdef FPC_PIC}
|
||||
ld [%g1+%l7],%g1
|
||||
{$endif FPC_PIC}
|
||||
stb %g0,[%g1]
|
||||
end;
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MEM_BARRIER}
|
||||
{$define FPC_SYSTEM_HAS_MEM_BARRIER}
|
||||
|
||||
const
|
||||
LoadLoad = $01;
|
||||
StoreLoad = $02;
|
||||
LoadStore = $04;
|
||||
StoreStore = $08;
|
||||
LookAside = $10;
|
||||
MemIssue = $20;
|
||||
Sync = $40;
|
||||
|
||||
{$if not(defined(SPARCV7)) and not(defined(SPARCV8))}
|
||||
{$define CPUSPARC_HAS_MEMBAR}
|
||||
{$endif}
|
||||
|
||||
procedure ReadBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
asm
|
||||
{$ifdef CPUSPARC_HAS_MEMBAR}
|
||||
ba,pt .L1
|
||||
membar LoadLoad
|
||||
.L1:
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
begin
|
||||
{ reads imply barrier on earlier reads depended on }
|
||||
end;
|
||||
|
||||
procedure ReadWriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
asm
|
||||
{$ifdef CPUSPARC_HAS_MEMBAR}
|
||||
ba,pt .L1
|
||||
membar LoadLoad + LoadStore + StoreLoad + StoreStore
|
||||
.L1:
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
procedure WriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
asm
|
||||
{$ifdef CPUSPARC_HAS_MEMBAR}
|
||||
ba,pt .L1
|
||||
stbar
|
||||
.L1:
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
{$endif}
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_SAR_QWORD}
|
||||
{$define FPC_SYSTEM_HAS_SAR_QWORD}
|
||||
function fpc_SarInt64(Const AValue : Int64;const Shift : Byte): Int64; [Public,Alias:'FPC_SARINT64']; compilerproc; assembler; nostackframe;
|
||||
asm
|
||||
{ %o0=high(AValue) %o1=low(AValue), result: %o0:%o1 }
|
||||
and %o2,63,%o2
|
||||
subcc %o2,32,%g0
|
||||
bcc .L1
|
||||
nop
|
||||
srl %o1,%o2,%o1
|
||||
subcc %o2,%g0,%g0
|
||||
be .Lexit
|
||||
sra %o0,%o2,%o0
|
||||
sub %g0,%o2,%o3
|
||||
sll %o0,%o3,%o3
|
||||
ba .Lexit
|
||||
or %o3,%o1,%o1
|
||||
.L1:
|
||||
sra %o0,%o2,%o1
|
||||
sra %o0,31,%o0
|
||||
.Lexit:
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_SAR_QWORD}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user