summaryrefslogtreecommitdiff
path: root/rtl/arm
diff options
context:
space:
mode:
authoryury <yury@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-09-15 18:06:36 +0000
committeryury <yury@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-09-15 18:06:36 +0000
commit05bb262de366fc10487de11d8499734fdcf66186 (patch)
treef6f877add0592c71409645d679da9f535085aa70 /rtl/arm
parentb466e8fa50bc43ae6042d52b5bc27bc90670c68b (diff)
downloadfpc-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.inc163
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}