Răsfoiți Sursa

m68k: reworked setjmp/longjmp to also save the FPU registers (when compiled with HW FPU support), and to only save the nonvolatile registers

git-svn-id: trunk@34785 -
Károly Balogh 8 ani în urmă
părinte
comite
7293bb7fdb
2 a modificat fișierele cu 43 adăugiri și 36 ștergeri
  1. 23 23
      rtl/m68k/setjump.inc
  2. 20 13
      rtl/m68k/setjumph.inc

+ 23 - 23
rtl/m68k/setjump.inc

@@ -1,7 +1,6 @@
 {
 {
     This file is part of the Free Pascal run time library.
     This file is part of the Free Pascal run time library.
-    Copyright (c) 1999-2000 by xxxx
-    member of the Free Pascal development team
+    Copyright (c) 1999-2016 by the Free Pascal development team.
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -18,20 +17,22 @@
 
 
 {$warning Fix register handling in case of nostackframe }
 {$warning Fix register handling in case of nostackframe }
 
 
-Function fpc_SetJmp (Var S : Jmp_buf) : longint;assembler;nostackframe;[Public, alias : 'FPC_SETJMP'];compilerproc;
+Function fpc_SetJmp (Var S : Jmp_buf) : longint;assembler;stdcall;nostackframe;[Public, alias : 'FPC_SETJMP'];compilerproc;
 asm
 asm
-  // Temporarily store a0 into d0
-  move.l a0,d0
   // load S to a0
   // load S to a0
   move.l 4(sp),a0
   move.l 4(sp),a0
 
 
-  // Save data registers d1..d7
-  movem.l d1/d2/d3/d4/d5/d6/d7,12(a0)
-  // Save address registers (a0-a5/a6, a0 is in d0 now)
+  // Save nonvolatile registers
 {$if defined(amiga)}
 {$if defined(amiga)}
-  movem.l d0/a1/a2/a3/a4/a6,40(a0) { amiga uses a5 as fp }
+  movem.l d2-d7/a2-a4/a6,12(a0)    { amiga uses a5 as fp }
 {$else}
 {$else}
-  movem.l d0/a1/a2/a3/a4/a5,40(a0)
+  movem.l d2-d7/a2-a5,12(a0)
+{$endif}
+
+{$if defined(fpu68881)}
+  fmovem.x  fp2-fp7,52(a0)
+{$elseif defined(fpucoldfire)}
+  fmovem.d  fp2-fp7,52(a0)
 {$endif}
 {$endif}
 
 
   // save return address (PC) and pop S off the stack
   // save return address (PC) and pop S off the stack
@@ -45,24 +46,21 @@ asm
   // 4 bytes already popped, 4 to go.
   // 4 bytes already popped, 4 to go.
   addq.l #4,d0
   addq.l #4,d0
   move.l d0,4(a0)
   move.l d0,4(a0)
-  // restore a0
-  move.l 40(a0),a0
 
 
   // return 0
   // return 0
   clr.l d0
   clr.l d0
 end;
 end;
 
 
-Procedure fpc_longJmp (Var S : Jmp_buf; value : longint); assembler;nostackframe;[Public, alias : 'FPC_LONGJMP'];compilerproc;
+Procedure fpc_longJmp (Var S : Jmp_buf; value : longint); assembler;stdcall;nostackframe;[Public, alias : 'FPC_LONGJMP'];compilerproc;
 asm
 asm
   // load S to a0
   // load S to a0
   move.l 4(sp),a0
   move.l 4(sp),a0
   // load 'value' to d0
   // load 'value' to d0
   move.l 8(sp),d0
   move.l 8(sp),d0
   // don't return zero
   // don't return zero
-  tst.l  d0
-  seq    d1
-  and.l #1,d1
-  or.l   d1,d0
+  bne @valueok
+  moveq.l #1,d0
+@valueok:
   // restore FP
   // restore FP
   move.l (a0),fp
   move.l (a0),fp
   // restore SP
   // restore SP
@@ -70,15 +68,17 @@ asm
   // jump to PC
   // jump to PC
   move.l 8(a0),-(sp)
   move.l 8(a0),-(sp)
 
 
-  // Restore data registers
-  movem.l 12(a0),d1/d2/d3/d4/d5/d6/d7
-
-  // Restore address registers
+  // Restore registers
 {$if defined(amiga)}
 {$if defined(amiga)}
-  movem.l 40(a0),a0/a1/a2/a3/a4/a6   { amiga uses a5 as fp }
+  movem.l 12(a0),d2-d7/a2-a4/a6    { amiga uses a5 as fp }
 {$else}
 {$else}
-  movem.l 40(a0),a0/a1/a2/a3/a4/a5
+  movem.l 12(a0),d2-d7/a2-a5
 {$endif}
 {$endif}
 
 
+{$if defined(fpu68881)}
+  fmovem.x  52(a0),fp2-fp7
+{$elseif defined(fpucoldfire)}
+  fmovem.d  52(a0),fp2-fp7
+{$endif}
   // new return pc is at (sp)
   // new return pc is at (sp)
 end;
 end;

+ 20 - 13
rtl/m68k/setjumph.inc

@@ -1,7 +1,6 @@
 {
 {
     This file is part of the Free Pascal run time library.
     This file is part of the Free Pascal run time library.
-    Copyright (c) 1999-2000 by xxxx
-    member of the Free Pascal development team
+    Copyright (c) 1999-2016 by the Free Pascal development team.
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -16,25 +15,33 @@
           Declarations for SetJmp/LongJmp
           Declarations for SetJmp/LongJmp
  **********************************************************************}
  **********************************************************************}
 
 
+type
+{$if defined(fpu68881)}
+  Tsizefpureg = packed array[0..11] of byte;
+{$elseif defined(fpucoldfire)}
+  Tsizefpureg = double;
+{$endif}
+
 Type
 Type
   jmp_buf = packed record
   jmp_buf = packed record
     fp : dword; { offset  0}   { frame pointer  (also a6)    }
     fp : dword; { offset  0}   { frame pointer  (also a6)    }
     sp : dword; { offset  4}   { stack pointer  (also a7)    }
     sp : dword; { offset  4}   { stack pointer  (also a7)    }
     pc : dword; { offset  8}   { program counter   }
     pc : dword; { offset  8}   { program counter   }
-    { There is no point in saving d0, as this is the register used to
-      return the vlaue of a function, which must be either zero
-      if called from SetJmp or value if called from LongJmp }
-    { data registers (d1, d2, d3, d4, d5, d6, d7) }
-    { offsets:        12, 16, 20, 24, 28, 32, 36 }
-    dregs : array[1..7] of dword;
-    { address registers (a0, a1, a2, a3, a4, a5), a6 and a7 are fp and sp respectively }
-    { offsets:           40, 44, 48, 52, 56, 60 }
-    aregs : array[0..5] of dword;
-    {Total size 64 bytes }
+
+    { data registers (d2, d3, d4, d5, d6, d7) }
+    { offsets:        12, 16, 20, 24, 28, 32 }
+    dregs : array[2..7] of dword;
+    { address registers (a2, a3, a4, a5), a6 and a7 are fp and sp respectively }
+    { offsets:           36, 40, 44, 48}
+    aregs : array[2..5] of dword;
+{$if defined(fpu68881) or defined(fpucoldfire)}
+    { offset: 52, size: 48 or 72 bytes, depending on FPU register size }
+    fregs : array[2..7] of tsizefpureg;
+{$endif}
+    { total size: 52, 100 or 124 bytes }
   end;
   end;
 
 
   PJmp_buf = ^jmp_buf;
   PJmp_buf = ^jmp_buf;
 
 
 Function Setjmp (Var S : Jmp_buf) : longint;[external name 'FPC_SETJMP'];
 Function Setjmp (Var S : Jmp_buf) : longint;[external name 'FPC_SETJMP'];
 Procedure longjmp (Var S : Jmp_buf; value : longint);[external name 'FPC_LONGJMP'];
 Procedure longjmp (Var S : Jmp_buf; value : longint);[external name 'FPC_LONGJMP'];
-