ソースを参照

+ edsp detection for arm-linux

git-svn-id: trunk@6429 -
florian 18 年 前
コミット
31c9a91af0
4 ファイル変更115 行追加4 行削除
  1. 102 1
      rtl/arm/arm.inc
  2. 8 1
      rtl/linux/arm/sighnd.inc
  3. 4 1
      rtl/linux/i386/sighnd.inc
  4. 1 1
      rtl/linux/system.pp

+ 102 - 1
rtl/arm/arm.inc

@@ -17,6 +17,12 @@
 
 {$asmmode gas}
 
+const
+  cpu_has_edsp : boolean = false;
+  in_edsp_test : boolean = false;
+var
+  moveproc : pointer;
+
 procedure fpc_cpuinit;
 begin
 {$if not(defined(wince)) and not(defined(gba)) and not(defined(nds))}
@@ -134,8 +140,10 @@ end;
 
 
 {$define FPC_SYSTEM_HAS_MOVE}
-procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;nostackframe;
+procedure Move_pld(const source;var dest;count:longint);assembler;nostackframe;
 asm
+  pld [r0]
+  pld [r1]
   // count <=0 ?
   cmp r2,#0
   movle pc,lr
@@ -182,9 +190,14 @@ asm
   tst r3,#7
   bne .Ldwordloop
 *)
+  pld [r0,#32]
+  pld [r1,#32]
 .Ldwordloop:
   sub r2,r2,#4
   ldr r3,[r0],#4
+  // preload
+  pld [r0,#64]
+  pld [r1,#64]
   cmp r2,#4
   str r3,[r1],#4
   bcs .Ldwordloop
@@ -198,6 +211,79 @@ asm
   mov pc,lr
 end;
 
+procedure Move_blended(const source;var dest;count:longint);assembler;nostackframe;
+asm
+  // count <=0 ?
+  cmp r2,#0
+  movle pc,lr
+  // overlap?
+  cmp r1,r0
+  bls .Lnooverlap
+  add r3,r0,r2
+  cmp r3,r1
+  bls .Lnooverlap
+  // overlap, copy backward
+.Loverlapped:
+  subs r2,r2,#1
+  ldrb r3,[r0,r2]
+  strb r3,[r1,r2]
+  bne .Loverlapped
+  mov pc,lr
+.Lnooverlap:
+  // less then 16 bytes to copy?
+  cmp r2,#8
+  // yes, the forget about the whole optimizations
+  // and do a bytewise copy
+  blt .Lbyteloop
+
+  // both aligned?
+  orr r3,r0,r1
+  tst r3,#3
+
+  bne .Lbyteloop
+(*
+  // yes, then align
+  // alignment to 4 byte boundries is enough
+  ldrb ip,[r0],#1
+  sub r2,r2,#1
+  stb ip,[r1],#1
+  tst r3,#2
+  bne .Ldifferentaligned
+  ldrh ip,[r0],#2
+  sub r2,r2,#2
+  sth ip,[r1],#2
+
+.Ldifferentaligned
+  // qword aligned?
+  orrs r3,r0,r1
+  tst r3,#7
+  bne .Ldwordloop
+*)
+.Ldwordloop:
+  sub r2,r2,#4
+  ldr r3,[r0],#4
+  cmp r2,#4
+  str r3,[r1],#4
+  bcs .Ldwordloop
+  cmp r2,#0
+  moveq pc,lr
+.Lbyteloop:
+  subs r2,r2,#1
+  ldrb r3,[r0],#1
+  strb r3,[r1],#1
+  bne .Lbyteloop
+  mov pc,lr
+end;
+
+
+procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE'];assembler;nostackframe;
+asm
+  ldr ip,.Lmoveproc
+  ldr pc,[ip]
+.Lmoveproc:
+  .long moveproc
+end;
+
 
 var
   fpc_system_lock: longint; export name 'fpc_system_lock';
@@ -312,3 +398,18 @@ procedure inclocked(var l: longint); inline;
 begin
   InterLockedIncrement(l);
 end;
+
+
+procedure fpc_cpucodeinit;
+begin
+  cpu_has_edsp:=true;
+  in_edsp_test:=true;
+  asm
+    pld [r0]
+  end;
+  in_edsp_test:=false;
+  if cpu_has_edsp then
+    moveproc:=@move_pld
+  else
+    moveproc:=@move_blended;
+end;

+ 8 - 1
rtl/linux/arm/sighnd.inc

@@ -28,7 +28,14 @@ begin
           { don't know how to find the different causes, maybe via xer? }
           res := 207;
         end;
-    SIGILL,
+    SIGILL:
+        if in_edsp_test then
+          begin
+            res:=0;
+            cpu_has_edsp:=false;
+          end
+        else
+          res:=216;
     SIGSEGV :
         res:=216;
     SIGBUS:

+ 4 - 1
rtl/linux/i386/sighnd.inc

@@ -66,7 +66,10 @@ begin
         res:=214;
     SIGILL:
         if sse_check then
-          res:=0
+          begin
+            os_supports_sse:=false;
+            res:=0;
+          end
         else
           res:=216;
     SIGSEGV :

+ 1 - 1
rtl/linux/system.pp

@@ -311,7 +311,7 @@ begin
   { Set up signals handlers }
   InstallSignals;
 
-{$if defined(cpui386)}
+{$if defined(cpui386) or defined(cpuarm)}
   fpc_cpucodeinit;
 {$endif cpui386}