|
@@ -321,15 +321,22 @@ asm
|
|
end;
|
|
end;
|
|
|
|
|
|
const
|
|
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
|
|
asm
|
|
ldr ip,.Lmoveproc
|
|
ldr ip,.Lmoveproc
|
|
ldr pc,[ip]
|
|
ldr pc,[ip]
|
|
.Lmoveproc:
|
|
.Lmoveproc:
|
|
.long moveproc
|
|
.long moveproc
|
|
end;
|
|
end;
|
|
|
|
+{$endif FPC_PIC}
|
|
|
|
+
|
|
{$endif CPUARM_HAS_EDSP}
|
|
{$endif CPUARM_HAS_EDSP}
|
|
|
|
|
|
{$endif FPC_SYSTEM_HAS_MOVE}
|
|
{$endif FPC_SYSTEM_HAS_MOVE}
|
|
@@ -541,10 +548,49 @@ asm
|
|
// Jump without a link, so freemem directly returns to our caller
|
|
// Jump without a link, so freemem directly returns to our caller
|
|
b FPC_FREEMEM
|
|
b FPC_FREEMEM
|
|
end;
|
|
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}
|
|
{$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;
|
|
function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
|
|
asm
|
|
asm
|
|
@@ -594,7 +640,18 @@ asm
|
|
|
|
|
|
{$else}
|
|
{$else}
|
|
// lock
|
|
// 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
|
|
mov r1, #1
|
|
.Lloop:
|
|
.Lloop:
|
|
swp r2, r1, [r3]
|
|
swp r2, r1, [r3]
|
|
@@ -613,37 +670,14 @@ asm
|
|
mov pc,lr
|
|
mov pc,lr
|
|
{$endif}
|
|
{$endif}
|
|
|
|
|
|
|
|
+{$ifndef FPC_PIC}
|
|
.Lfpc_system_lock:
|
|
.Lfpc_system_lock:
|
|
.long fpc_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}
|
|
{$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;
|
|
end;
|
|
-{$endif not darwin}
|
|
|
|
|
|
|
|
function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
|
|
function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
|
|
asm
|
|
asm
|
|
@@ -691,7 +725,18 @@ asm
|
|
|
|
|
|
{$else}
|
|
{$else}
|
|
// lock
|
|
// 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
|
|
mov r1, #1
|
|
.Lloop:
|
|
.Lloop:
|
|
swp r2, r1, [r3]
|
|
swp r2, r1, [r3]
|
|
@@ -710,13 +755,15 @@ asm
|
|
mov pc,lr
|
|
mov pc,lr
|
|
{$endif}
|
|
{$endif}
|
|
|
|
|
|
|
|
+{$ifndef FPC_PIC}
|
|
.Lfpc_system_lock:
|
|
.Lfpc_system_lock:
|
|
.long fpc_system_lock
|
|
.long fpc_system_lock
|
|
|
|
+{$endif FPC_PIC}
|
|
|
|
+
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
-
|
|
|
|
function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
|
|
function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
|
|
asm
|
|
asm
|
|
{$ifdef CPUARM_HAS_LDREX}
|
|
{$ifdef CPUARM_HAS_LDREX}
|
|
@@ -763,7 +810,18 @@ asm
|
|
b .Latomic_add_loop // kuser_cmpxchg failed, loop back
|
|
b .Latomic_add_loop // kuser_cmpxchg failed, loop back
|
|
{$else}
|
|
{$else}
|
|
// lock
|
|
// 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
|
|
mov r2, #1
|
|
.Lloop:
|
|
.Lloop:
|
|
swp r2, r2, [r3]
|
|
swp r2, r2, [r3]
|
|
@@ -782,8 +840,11 @@ asm
|
|
mov pc,lr
|
|
mov pc,lr
|
|
{$endif}
|
|
{$endif}
|
|
|
|
|
|
|
|
+{$ifndef FPC_PIC}
|
|
.Lfpc_system_lock:
|
|
.Lfpc_system_lock:
|
|
.long fpc_system_lock
|
|
.long fpc_system_lock
|
|
|
|
+{$endif FPC_PIC}
|
|
|
|
+
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
end;
|
|
end;
|
|
@@ -839,7 +900,18 @@ asm
|
|
|
|
|
|
{$else}
|
|
{$else}
|
|
// lock
|
|
// 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
|
|
mov r2, #1
|
|
.Lloop:
|
|
.Lloop:
|
|
swp r2, r2, [r3]
|
|
swp r2, r2, [r3]
|
|
@@ -859,8 +931,11 @@ asm
|
|
mov pc,lr
|
|
mov pc,lr
|
|
{$endif}
|
|
{$endif}
|
|
|
|
|
|
|
|
+{$ifndef FPC_PIC}
|
|
.Lfpc_system_lock:
|
|
.Lfpc_system_lock:
|
|
.long fpc_system_lock
|
|
.long fpc_system_lock
|
|
|
|
+{$endif FPC_PIC}
|
|
|
|
+
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
end;
|
|
end;
|
|
@@ -918,7 +993,18 @@ asm
|
|
|
|
|
|
{$else}
|
|
{$else}
|
|
// lock
|
|
// 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
|
|
mov r3, #1
|
|
.Lloop:
|
|
.Lloop:
|
|
swp r3, r3, [r12]
|
|
swp r3, r3, [r12]
|
|
@@ -938,8 +1024,11 @@ asm
|
|
mov pc,lr
|
|
mov pc,lr
|
|
{$endif}
|
|
{$endif}
|
|
|
|
|
|
|
|
+{$ifndef FPC_PIC}
|
|
.Lfpc_system_lock:
|
|
.Lfpc_system_lock:
|
|
.long fpc_system_lock
|
|
.long fpc_system_lock
|
|
|
|
+{$endif FPC_PIC}
|
|
|
|
+
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
{$endif}
|
|
end;
|
|
end;
|
|
@@ -956,6 +1045,8 @@ begin
|
|
InterLockedIncrement(l);
|
|
InterLockedIncrement(l);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+// --- InterLocked functions end
|
|
|
|
+
|
|
procedure fpc_cpucodeinit;
|
|
procedure fpc_cpucodeinit;
|
|
begin
|
|
begin
|
|
{$ifdef FPC_SYSTEM_FPC_MOVE}
|
|
{$ifdef FPC_SYSTEM_FPC_MOVE}
|