diff options
author | yury <yury@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-09-15 18:06:36 +0000 |
---|---|---|
committer | yury <yury@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-09-15 18:06:36 +0000 |
commit | 05bb262de366fc10487de11d8499734fdcf66186 (patch) | |
tree | f6f877add0592c71409645d679da9f535085aa70 /rtl/arm | |
parent | b466e8fa50bc43ae6042d52b5bc27bc90670c68b (diff) | |
download | fpc-05bb262de366fc10487de11d8499734fdcf66186.tar.gz |
* ARM assembler routines are PIC compatible now.
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@31703 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/arm')
-rw-r--r-- | rtl/arm/arm.inc | 163 |
1 files changed, 127 insertions, 36 deletions
diff --git a/rtl/arm/arm.inc b/rtl/arm/arm.inc index 9cfe26c6b7..bfdb7fc94a 100644 --- a/rtl/arm/arm.inc +++ b/rtl/arm/arm.inc @@ -335,15 +335,22 @@ asm end; const - moveproc : pointer = @move_blended; + moveproc : procedure(const source;var dest;count:longint) = @move_blended; -procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;nostackframe; +procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE']; {$ifndef FPC_PIC} assembler;nostackframe; {$endif FPC_PIC} +{$ifdef FPC_PIC} +begin + moveproc(source,dest,count); +end; +{$else FPC_PIC} asm ldr ip,.Lmoveproc ldr pc,[ip] .Lmoveproc: .long moveproc end; +{$endif FPC_PIC} + {$endif CPUARM_HAS_EDSP} {$endif FPC_SYSTEM_HAS_MOVE} @@ -555,10 +562,49 @@ asm // Jump without a link, so freemem directly returns to our caller b FPC_FREEMEM end; + +{$define FPC_SYSTEM_HAS_ANSISTR_INCR_REF} +Procedure fpc_ansistr_incr_ref (S : Pointer); [Public,Alias:'FPC_ANSISTR_INCR_REF'];assembler;nostackframe; compilerproc; +asm + // Null string? + cmp r0, #0 + // Load reference counter + ldrne r1, [r0, #-8] + // pointer to counter, calculate here for delay slot utilization + subne r0, r0, #8 +{$ifdef CPUARM_HAS_BX} + bxeq lr +{$else} + moveq pc,lr +{$endif} + // Check for a constant string + cmp r1, #0 + // Tailcall + // Hopefully the linker will place InterLockedIncrement as layed out here + bge InterLockedIncrement + // Freepascal will generate a proper return here, save some cachespace +end; {$endif not darwin} -var - fpc_system_lock: longint; export name 'fpc_system_lock'; +// --- InterLocked functions begin + +{$if not defined(CPUARM_HAS_LDREX) and not defined(SYSTEM_HAS_KUSER_CMPXCHG) } + // Use generic interlock implementation + + var + fpc_system_lock: longint; + + {$ifdef FPC_PIC} + // Use generic interlock implementation with PIC + + // A helper function to get a pointer to fpc_system_lock in the PIC compatible way. + function get_fpc_system_lock_ptr: pointer; + begin + get_fpc_system_lock_ptr:=@fpc_system_lock; + end; + + {$endif FPC_PIC} +{$endif} function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe; asm @@ -608,7 +654,18 @@ asm {$else} // lock - ldr r3, .Lfpc_system_lock + {$ifdef FPC_PIC} + push {r0,lr} + {$ifdef CPUARM_HAS_BLX} + blx get_fpc_system_lock_ptr + {$else} + bl get_fpc_system_lock_ptr + {$endif CPUARM_HAS_BLX} + mov r3,r0 + pop {r0,lr} + {$else FPC_PIC} + ldr r3, .Lfpc_system_lock + {$endif FPC_PIC} mov r1, #1 .Lloop: swp r2, r1, [r3] @@ -627,37 +684,14 @@ asm mov pc,lr {$endif} +{$ifndef FPC_PIC} .Lfpc_system_lock: .long fpc_system_lock -{$endif} -{$endif} -end; - - -{$ifndef darwin} -{$define FPC_SYSTEM_HAS_ANSISTR_INCR_REF} +{$endif FPC_PIC} -Procedure fpc_ansistr_incr_ref (S : Pointer); [Public,Alias:'FPC_ANSISTR_INCR_REF'];assembler;nostackframe; compilerproc; -asm - // Null string? - cmp r0, #0 - // Load reference counter - ldrne r1, [r0, #-8] - // pointer to counter, calculate here for delay slot utilization - subne r0, r0, #8 -{$ifdef CPUARM_HAS_BX} - bxeq lr -{$else} - moveq pc,lr {$endif} - // Check for a constant string - cmp r1, #0 - // Tailcall - // Hopefully the linker will place InterLockedIncrement as layed out here - bge InterLockedIncrement - // Freepascal will generate a proper return here, save some cachespace +{$endif} end; -{$endif not darwin} function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe; asm @@ -705,7 +739,18 @@ asm {$else} // lock - ldr r3, .Lfpc_system_lock + {$ifdef FPC_PIC} + push {r0,lr} + {$ifdef CPUARM_HAS_BLX} + blx get_fpc_system_lock_ptr + {$else} + bl get_fpc_system_lock_ptr + {$endif CPUARM_HAS_BLX} + mov r3,r0 + pop {r0,lr} + {$else FPC_PIC} + ldr r3, .Lfpc_system_lock + {$endif FPC_PIC} mov r1, #1 .Lloop: swp r2, r1, [r3] @@ -724,13 +769,15 @@ asm mov pc,lr {$endif} +{$ifndef FPC_PIC} .Lfpc_system_lock: .long fpc_system_lock +{$endif FPC_PIC} + {$endif} {$endif} end; - function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe; asm {$ifdef CPUARM_HAS_LDREX} @@ -777,7 +824,18 @@ asm b .Latomic_add_loop // kuser_cmpxchg failed, loop back {$else} // lock - ldr r3, .Lfpc_system_lock + {$ifdef FPC_PIC} + push {r0,r1,lr} + {$ifdef CPUARM_HAS_BLX} + blx get_fpc_system_lock_ptr + {$else} + bl get_fpc_system_lock_ptr + {$endif CPUARM_HAS_BLX} + mov r3,r0 + pop {r0,r1,lr} + {$else FPC_PIC} + ldr r3, .Lfpc_system_lock + {$endif FPC_PIC} mov r2, #1 .Lloop: swp r2, r2, [r3] @@ -796,8 +854,11 @@ asm mov pc,lr {$endif} +{$ifndef FPC_PIC} .Lfpc_system_lock: .long fpc_system_lock +{$endif FPC_PIC} + {$endif} {$endif} end; @@ -853,7 +914,18 @@ asm {$else} // lock - ldr r3, .Lfpc_system_lock + {$ifdef FPC_PIC} + push {r0,r1,lr} + {$ifdef CPUARM_HAS_BLX} + blx get_fpc_system_lock_ptr + {$else} + bl get_fpc_system_lock_ptr + {$endif CPUARM_HAS_BLX} + mov r3,r0 + pop {r0,r1,lr} + {$else FPC_PIC} + ldr r3, .Lfpc_system_lock + {$endif FPC_PIC} mov r2, #1 .Lloop: swp r2, r2, [r3] @@ -873,8 +945,11 @@ asm mov pc,lr {$endif} +{$ifndef FPC_PIC} .Lfpc_system_lock: .long fpc_system_lock +{$endif FPC_PIC} + {$endif} {$endif} end; @@ -930,7 +1005,18 @@ asm {$else} // lock - ldr r12, .Lfpc_system_lock + {$ifdef FPC_PIC} + push {r0,r1,r2,lr} + {$ifdef CPUARM_HAS_BLX} + blx get_fpc_system_lock_ptr + {$else} + bl get_fpc_system_lock_ptr + {$endif CPUARM_HAS_BLX} + mov r12,r0 + pop {r0,r1,r2,lr} + {$else FPC_PIC} + ldr r12, .Lfpc_system_lock + {$endif FPC_PIC} mov r3, #1 .Lloop: swp r3, r3, [r12] @@ -950,8 +1036,11 @@ asm mov pc,lr {$endif} +{$ifndef FPC_PIC} .Lfpc_system_lock: .long fpc_system_lock +{$endif FPC_PIC} + {$endif} {$endif} end; @@ -968,6 +1057,8 @@ begin InterLockedIncrement(l); end; +// --- InterLocked functions end + procedure fpc_cpucodeinit; begin {$ifdef FPC_SYSTEM_FPC_MOVE} |