From b9770519f8245212b2d135801391a032711b0e6e Mon Sep 17 00:00:00 2001 From: masta Date: Wed, 8 Aug 2012 06:44:31 +0000 Subject: [PATCH] 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 - --- rtl/arm/arm.inc | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/rtl/arm/arm.inc b/rtl/arm/arm.inc index 652c6a4f26..db5a439871 100644 --- a/rtl/arm/arm.inc +++ b/rtl/arm/arm.inc @@ -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';