Przeglądaj źródła

* ARM assembler routines are PIC compatible now.

git-svn-id: trunk@31703 -
yury 10 lat temu
rodzic
commit
9f2ef7c546
1 zmienionych plików z 127 dodań i 36 usunięć
  1. 127 36
      rtl/arm/arm.inc

+ 127 - 36
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}