mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 07:34:28 +02:00
really fixed FillChar and fixed FillWord. fixes 8 tests.
git-svn-id: trunk@25622 -
This commit is contained in:
parent
e27db65085
commit
d004b44406
@ -14,6 +14,92 @@
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
var
|
||||
// This is a BSS variable, so it will be initialized to #0
|
||||
// This HAS to be larger than the amount if FPC_SETJMP call in the binary
|
||||
// To avoid excessive linear searches use at least Calls*1.5 rounded up to the next power of 2
|
||||
// If the size gets changed, the code below also needs adjustment
|
||||
setjmp_counter: array[0..$2000-1] of TSetJmpCounter;
|
||||
|
||||
// This function MUST return 0
|
||||
function fpc_count_setjmp: LongInt; assembler; nostackframe;
|
||||
asm
|
||||
// lr = Original Address
|
||||
// r0 = HashValue = (Address >> 2) and $1FFF
|
||||
// r1 = HashBase
|
||||
// r2 = CallerAddress in hashtable
|
||||
// r3 = Counter
|
||||
|
||||
// Those two shifts are the "hashfunction"
|
||||
// The result can be used as an index into the hashtable
|
||||
// These required shift amount can be calculated like this
|
||||
// lshift = 32-clz($hashmask)-2
|
||||
// rshift = rshift - 1
|
||||
// This only works on ARM-Code where the lower two lr bits are always 0
|
||||
ldr r1, .LCounterBuffer
|
||||
mov r0, lr, lsl #17
|
||||
mov r0, r0, lsr #16
|
||||
|
||||
.LSlotLoop:
|
||||
// Did we wrap?
|
||||
tst r0, #0x10000
|
||||
// If so, reset to #0
|
||||
movne r0, #0
|
||||
|
||||
// Load Address and counter
|
||||
ldrd r2, r3, [r1, r0]
|
||||
|
||||
// If the Address is 0, create a new slot
|
||||
cmp r2, #0
|
||||
beq .LNewSlot
|
||||
|
||||
// A once set Address is not going to change!
|
||||
cmp r2, lr
|
||||
// Address did not match? Next!
|
||||
addne r0, r0, #8
|
||||
bne .LSlotLoop
|
||||
|
||||
// We'll not increment atomicaly here, because that has a lot of overhead
|
||||
// and very little gain, we might miss a small amount of calls, but thats not a big issue
|
||||
// Increment counter
|
||||
add r3, r3, #1
|
||||
// Adjust base to be on the counter
|
||||
add r0, r0, #4
|
||||
str r3, [r1, r0]
|
||||
mov r0, #0
|
||||
bx lr
|
||||
|
||||
.LNewSlot:
|
||||
stmfd sp!, {r0, r1, r2, lr}
|
||||
add r0, r0, r1 // Address of the address ...
|
||||
mov r1, lr // New value
|
||||
mov r2, #0 // OldValue
|
||||
blx InterlockedCompareExchange
|
||||
ldmfd sp!, {r0, r1, r2, lr}
|
||||
b .LSlotLoop
|
||||
|
||||
.LCounterBuffer:
|
||||
.long setjmp_counter
|
||||
end;
|
||||
|
||||
procedure fpc_dump_setjmp;
|
||||
var cnt: LongInt;
|
||||
begin
|
||||
for cnt:=Low(setjmp_counter) to High(setjmp_counter) do
|
||||
begin
|
||||
if setjmp_counter[cnt].counter > 0 then
|
||||
begin
|
||||
writeln('Address: [$',hexstr(setjmp_counter[cnt].Address - 4,8), '] Count:',setjmp_counter[cnt].Counter);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function fpc_setjmp_table_entry(idx: LongWord): PSetJmpCounter;
|
||||
begin
|
||||
fpc_setjmp_table_entry:=nil;
|
||||
if (idx < $2000) then fpc_setjmp_table_entry:=@setjmp_counter[idx];
|
||||
end;
|
||||
|
||||
function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_SETJMP'];nostackframe; compilerproc;
|
||||
asm
|
||||
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
||||
@ -52,12 +138,7 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S
|
||||
bx lr
|
||||
{$else}
|
||||
stmia r0,{v1-v6, sl, fp, sp, lr}
|
||||
mov r0,#0
|
||||
{$ifdef CPUARM_HAS_BX}
|
||||
bx lr
|
||||
{$else}
|
||||
mov pc,lr
|
||||
{$endif}
|
||||
b fpc_count_setjmp
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
@ -26,4 +26,12 @@ type
|
||||
function setjmp(var S : jmp_buf) : longint;[external name 'FPC_SETJMP'];
|
||||
procedure longjmp(var S : jmp_buf;value : longint);[external name 'FPC_LONGJMP'];
|
||||
|
||||
type
|
||||
TSetJmpCounter = record
|
||||
Address: LongWord;
|
||||
Counter: LongWord;
|
||||
end;
|
||||
PSetJmpCounter = ^TSetJmpCounter;
|
||||
|
||||
procedure fpc_dump_setjmp;
|
||||
function fpc_setjmp_table_entry(idx: LongWord): PSetJmpCounter;
|
||||
|
@ -949,6 +949,11 @@ Begin
|
||||
{$ifdef SYSTEMDEBUG}
|
||||
writeln('InternalExit');
|
||||
{$endif SYSTEMDEBUG}
|
||||
|
||||
{$IFDEF CPUARM}
|
||||
fpc_dump_setjmp;
|
||||
{$ENDIF}
|
||||
|
||||
while exitProc<>nil Do
|
||||
Begin
|
||||
InOutRes:=0;
|
||||
|
Loading…
Reference in New Issue
Block a user