mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-08 10:39:29 +02:00
Save complete register set for setjmp/longjmp
git-svn-id: trunk@23174 -
This commit is contained in:
parent
0e14a3c5bd
commit
76ba2ea6c7
@ -18,8 +18,12 @@
|
||||
|
||||
Function fpc_SetJmp (Var S : Jmp_buf) : longint;assembler;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
|
||||
move.l S, a0
|
||||
// save a0 (now in d0) to offset 40
|
||||
move.l d0, 40(a0)
|
||||
// save return address (PC)
|
||||
move.l (sp), d0
|
||||
move.l d0, 8(a0)
|
||||
@ -28,7 +32,31 @@ asm
|
||||
// save SP
|
||||
move.l sp, d0
|
||||
addq.l #8, d0
|
||||
move.l d0, 4(a0)
|
||||
move.l d0, (a0)
|
||||
// save a1
|
||||
move.l a1,d0
|
||||
move.l d0,44(a0)
|
||||
// save a2
|
||||
move.l a2,d0
|
||||
move.l d0,48(a0)
|
||||
// save a3
|
||||
move.l a3,d0
|
||||
move.l d0,52(a0)
|
||||
// save a4
|
||||
move.l a4,d0
|
||||
move.l d0,56(a0)
|
||||
// save a5
|
||||
move.l a5,d0
|
||||
move.l d0,60(a0)
|
||||
// save d1..d7
|
||||
move d1, 12(a0)
|
||||
move d2, 16(a0)
|
||||
move d3, 20(a0)
|
||||
move d4, 24(a0)
|
||||
move d5, 28(a0)
|
||||
move d6, 32(a0)
|
||||
move d7, 36(a0)
|
||||
|
||||
// return 0
|
||||
clr.l d0
|
||||
end;
|
||||
@ -36,14 +64,50 @@ end;
|
||||
Procedure fpc_longJmp (Var S : Jmp_buf; value : longint); assembler;nostackframe;[Public, alias : 'FPC_LONGJMP'];compilerproc;
|
||||
asm
|
||||
// load S to a0
|
||||
move.l 4(sp),a0
|
||||
move.l S,a0
|
||||
// Restore address registers
|
||||
// restore a1
|
||||
move.l 44(a0),d0
|
||||
move.l d0,a1
|
||||
// restore a2
|
||||
move.l 48(a0),d0
|
||||
move.l d0,a2
|
||||
// restore a3
|
||||
move.l 52(a0),d0
|
||||
move.l d0,a3
|
||||
// restore a4
|
||||
move.l 56(a0),d0
|
||||
move.l d0,a4
|
||||
// restore a5
|
||||
move.l 60(a0),d0
|
||||
move.l d0,a5
|
||||
// restore d1..d7
|
||||
move 12(a0),d1
|
||||
move 16(a0),d2
|
||||
move 20(a0),d3
|
||||
move 24(a0),d4
|
||||
move 28(a0),d5
|
||||
move 32(a0),d6
|
||||
move 36(a0),d7
|
||||
|
||||
// load value to d0
|
||||
move.l 8(sp),d0
|
||||
move.l value,d0
|
||||
// Save temporarily into d1 slot
|
||||
move.l d0,12(a0)
|
||||
// restore FP
|
||||
move.l (a0), a6
|
||||
// restore SP
|
||||
move.l 4(a0), sp
|
||||
// jump to PC
|
||||
move.l 8(a0),a0
|
||||
jmp (a0)
|
||||
move.l 8(a0),d0
|
||||
move.l d0,-(sp)
|
||||
// restore a0
|
||||
move.l 40(a0),d0
|
||||
move.l d0,-(sp)
|
||||
// restore return value, now at 12(a0)
|
||||
move.l 12(a0),d0
|
||||
// restore a0 from stack
|
||||
move.l (sp)+,a0
|
||||
// new return pc is at (sp), so we can call rts
|
||||
rts
|
||||
end;
|
||||
|
@ -18,11 +18,21 @@
|
||||
|
||||
Type
|
||||
jmp_buf = packed record
|
||||
fp : longint; { frame pointer }
|
||||
sp : longint; { stack pointer }
|
||||
pc : longint; { program counter }
|
||||
aregs : array[0..3] of dword; { address registers (a2,a3,a4,a5) }
|
||||
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[0..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 }
|
||||
end;
|
||||
|
||||
PJmp_buf = ^jmp_buf;
|
||||
|
||||
Function Setjmp (Var S : Jmp_buf) : longint;[external name 'FPC_SETJMP'];
|
||||
|
Loading…
Reference in New Issue
Block a user