Browse Source

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 years ago
parent
commit
7293bb7fdb
2 changed files with 43 additions and 36 deletions
  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.
-    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,
     for details about the copyright.
@@ -18,20 +17,22 @@
 
 {$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
-  // Temporarily store a0 into d0
-  move.l a0,d0
   // load S to 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)}
-  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}
-  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}
 
   // save return address (PC) and pop S off the stack
@@ -45,24 +46,21 @@ asm
   // 4 bytes already popped, 4 to go.
   addq.l #4,d0
   move.l d0,4(a0)
-  // restore a0
-  move.l 40(a0),a0
 
   // return 0
   clr.l d0
 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
   // load S to a0
   move.l 4(sp),a0
   // load 'value' to d0
   move.l 8(sp),d0
   // 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
   move.l (a0),fp
   // restore SP
@@ -70,15 +68,17 @@ asm
   // jump to PC
   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)}
-  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}
-  movem.l 40(a0),a0/a1/a2/a3/a4/a5
+  movem.l 12(a0),d2-d7/a2-a5
 {$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)
 end;

+ 20 - 13
rtl/m68k/setjumph.inc

@@ -1,7 +1,6 @@
 {
     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,
     for details about the copyright.
@@ -16,25 +15,33 @@
           Declarations for SetJmp/LongJmp
  **********************************************************************}
 
+type
+{$if defined(fpu68881)}
+  Tsizefpureg = packed array[0..11] of byte;
+{$elseif defined(fpucoldfire)}
+  Tsizefpureg = double;
+{$endif}
+
 Type
   jmp_buf = packed record
     fp : dword; { offset  0}   { frame pointer  (also a6)    }
     sp : dword; { offset  4}   { stack pointer  (also a7)    }
     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;
 
   PJmp_buf = ^jmp_buf;
 
 Function Setjmp (Var S : Jmp_buf) : longint;[external name 'FPC_SETJMP'];
 Procedure longjmp (Var S : Jmp_buf; value : longint);[external name 'FPC_LONGJMP'];
-