mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 07:28:26 +02:00
Assembly version of fpc_ansistr_decr_ref for ARM
As fpc_ansistr_decr_ref is a very often called procedure in typical pascal programs this optimized version will shave off some cycles compared to the generic one. It tries to avoid load latencies as much as possible and also uses the new Z-flag functionality of the InterlockedDecrement from the previous patch. Also FreeMem is called as a tail-function. git-svn-id: trunk@22034 -
This commit is contained in:
parent
25e2f5f3fa
commit
b9770519f8
@ -499,6 +499,50 @@ end;
|
||||
{$endif}
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_ANSISTR_DECR_REF}
|
||||
function fpc_freemem_x(p:pointer):ptrint; [external name 'FPC_FREEMEM_X'];
|
||||
|
||||
Procedure fpc_ansistr_decr_ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DECR_REF'];assembler;nostackframe; compilerproc;
|
||||
asm
|
||||
ldr r1, [r0]
|
||||
// On return the pointer will always be set to zero, so utilize the delay slots
|
||||
mov r2, #0
|
||||
str r2, [r0]
|
||||
|
||||
// Check for a zero string
|
||||
cmp r1, #0
|
||||
// Load reference counter
|
||||
ldrne r2, [r1, #-8]
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4)}
|
||||
moveq pc,lr
|
||||
{$else}
|
||||
bxeq lr
|
||||
{$endif}
|
||||
// Check for a constant string
|
||||
cmp r2, #0
|
||||
{$if defined(cpuarmv3) or defined(cpuarmv4)}
|
||||
movlt pc,lr
|
||||
{$else}
|
||||
bxlt lr
|
||||
{$endif}
|
||||
stmfd sp!, {r1, lr}
|
||||
sub r0, r1, #8
|
||||
blx InterLockedDecrement
|
||||
// InterLockedDecrement is a nice guy and sets the z flag for us
|
||||
// if the reference count dropped to 0
|
||||
ldmnefd sp!, {r1, pc}
|
||||
ldmfd sp!, {r0, lr}
|
||||
// We currently can not use constant symbols in ARM-Assembly
|
||||
// but we need to stay backward compatible with 2.6
|
||||
{$if defined(VER2_6)}
|
||||
sub r0, r0, #8 //AnsiFirstOff in 2.6
|
||||
{$else}
|
||||
sub r0, r0, #12 //AnsiFirstOff in 2.7 with codepage support
|
||||
{$endif}
|
||||
// Jump without a link, so freemem directly returns to our caller
|
||||
b FPC_FREEMEM_X
|
||||
end;
|
||||
|
||||
var
|
||||
fpc_system_lock: longint; export name 'fpc_system_lock';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user