Prechádzať zdrojové kódy

Save complete register set for setjmp/longjmp

git-svn-id: trunk@23174 -
pierre 12 rokov pred
rodič
commit
76ba2ea6c7
2 zmenil súbory, kde vykonal 84 pridanie a 10 odobranie
  1. 70 6
      rtl/m68k/setjump.inc
  2. 14 4
      rtl/m68k/setjumph.inc

+ 70 - 6
rtl/m68k/setjump.inc

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

+ 14 - 4
rtl/m68k/setjumph.inc

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