|
@@ -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}
|