Save complete register set for setjmp/longjmp

git-svn-id: trunk@23174 -
This commit is contained in:
pierre 2012-12-18 14:05:52 +00:00
parent 0e14a3c5bd
commit 76ba2ea6c7
2 changed files with 84 additions and 10 deletions

View File

@ -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;

View File

@ -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'];