mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 18:49:11 +02:00
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 -
This commit is contained in:
parent
37f43d3604
commit
7293bb7fdb
@ -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
|
Copyright (c) 1999-2016 by the Free Pascal development team.
|
||||||
member of 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
|
// Save nonvolatile registers
|
||||||
movem.l d1/d2/d3/d4/d5/d6/d7,12(a0)
|
|
||||||
// Save address registers (a0-a5/a6, a0 is in d0 now)
|
|
||||||
{$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
|
bne @valueok
|
||||||
seq d1
|
moveq.l #1,d0
|
||||||
and.l #1,d1
|
@valueok:
|
||||||
or.l d1,d0
|
|
||||||
// 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
|
// Restore registers
|
||||||
movem.l 12(a0),d1/d2/d3/d4/d5/d6/d7
|
|
||||||
|
|
||||||
// Restore address 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;
|
||||||
|
@ -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
|
Copyright (c) 1999-2016 by the Free Pascal development team.
|
||||||
member of 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
|
{ data registers (d2, d3, d4, d5, d6, d7) }
|
||||||
if called from SetJmp or value if called from LongJmp }
|
{ offsets: 12, 16, 20, 24, 28, 32 }
|
||||||
{ data registers (d1, d2, d3, d4, d5, d6, d7) }
|
dregs : array[2..7] of dword;
|
||||||
{ offsets: 12, 16, 20, 24, 28, 32, 36 }
|
{ address registers (a2, a3, a4, a5), a6 and a7 are fp and sp respectively }
|
||||||
dregs : array[1..7] of dword;
|
{ offsets: 36, 40, 44, 48}
|
||||||
{ address registers (a0, a1, a2, a3, a4, a5), a6 and a7 are fp and sp respectively }
|
aregs : array[2..5] of dword;
|
||||||
{ offsets: 40, 44, 48, 52, 56, 60 }
|
{$if defined(fpu68881) or defined(fpucoldfire)}
|
||||||
aregs : array[0..5] of dword;
|
{ offset: 52, size: 48 or 72 bytes, depending on FPU register size }
|
||||||
{Total size 64 bytes }
|
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'];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user