setjump.inc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2002 by Jonas Maebe and other members of the
  5. Free Pascal development team
  6. SetJmp and LongJmp implementation for exception handling
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {#define ENV(base,reg) [%base + (reg * 4)]
  14. #define ST_FLUSH_WINDOWS 3
  15. #define RW_FP [%fp + 0x48]
  16. }
  17. {$ifdef linux}
  18. {$define needsigprocmask}
  19. {$endif}
  20. {$ifdef needsigprocmask}
  21. const
  22. JMPSIG_BLOCK = 1;
  23. JMPSIG_SETMASK = 4;
  24. function JmpSigProcMask(how:longint;nset : pjmpsigset;oset : pjmpsigset):longint; external name 'FPC_SYSC_SIGPROCMASK';
  25. procedure savesigmask(var s:jmp_buf);
  26. begin
  27. jmpsigprocmask(JMPSIG_BLOCK,nil,@s.sigmask);
  28. end;
  29. procedure restoresigmask(var s:jmp_buf);
  30. begin
  31. jmpsigprocmask(JMPSIG_SETMASK,@s.sigmask,nil);
  32. end;
  33. {$endif needsigprocmask}
  34. procedure longjmp(var s : jmp_buf;value:longint);assembler;nostackframe;[Public,alias:'FPC_LONGJMP'];
  35. asm
  36. // Store our arguments in global registers so we can still
  37. // use them while unwinding frames and their register windows.
  38. ld [%o0+4], %g3 // Cache target FP in register %g3.
  39. mov %o0, %g1 // s in %g1
  40. orcc %o1, %g0, %g2 // value in %g2
  41. be,a .L0 // Branch if zero; else skip delay slot.
  42. mov 1, %g2 // Delay slot only hit if zero: VAL = 1.
  43. .L0:
  44. xor %fp, %g3, %o0
  45. add %fp, 512, %o1
  46. andncc %o0, 4095, %o0
  47. bne .Lthread
  48. cmp %o1, %g3
  49. bl .Lthread
  50. // Now we will loop, unwinding the register windows up the stack
  51. // until the restored %fp value matches the target value in %g3.
  52. .Lloop:
  53. cmp %fp, %g3 // Have we reached the target frame?
  54. bl,a .Lloop // Loop while current fp is below target.
  55. restore // Unwind register window in delay slot.
  56. be,a .Lfound // Better have hit it exactly.
  57. ld [%g1], %o0 // Delay slot: extract target SP.
  58. .Lthread:
  59. {
  60. * Do a "flush register windows trap". The trap handler in the
  61. * kernel writes all the register windows to their stack slots, and
  62. * marks them all as invalid (needing to be sucked up from the
  63. * stack when used). This ensures that all information needed to
  64. * unwind to these callers is in memory, not in the register
  65. * windows.
  66. }
  67. ta 3
  68. mov %g1,%o1 // use %o1, since %g1 will be destroyed by the call below
  69. ld [%o1], %fp // Set saved SP on restore below.
  70. sub %fp, 64, %sp // Allocate a register frame.
  71. st %g3, [%fp+48] // Set saved FP on restore below.
  72. {$ifdef needsigprocmask}
  73. mov %o1,%o0
  74. call restoresigmask
  75. nop
  76. {$endif needsigprocmask}
  77. ld [%o1+8], %o7 // Set return PC.
  78. retl
  79. restore %g2, 0, %o0 // Restore values from above register frame.
  80. .Lfound:
  81. // We have unwound register windows so %fp matches the target.
  82. mov %o0, %sp // OK, install new SP.
  83. .Lsp_ok:
  84. ld [%g1+8], %o0 // Extract target return PC.
  85. jmp %o0+8 // Return there.
  86. mov %g2, %o0 // Delay slot: set return value.
  87. end;
  88. function setjmp(var S:jmp_buf):longint;assembler;nostackframe;[Public,alias:'FPC_SETJMP'];
  89. asm
  90. // We don't create a stackframe so we can save PC,SP and FP of the caller
  91. st %o7, [%o0+8]
  92. st %sp, [%o0]
  93. st %fp, [%o0+4]
  94. {$ifdef needsigprocmask}
  95. call savesigmask
  96. nop
  97. {$endif needsigprocmask}
  98. ld [%o0+8], %o7
  99. mov %g0, %o0
  100. end;
  101. {
  102. $Log$
  103. Revision 1.9 2004-09-12 12:04:22 peter
  104. * restore traps when returning with longjmp
  105. Revision 1.8 2004/05/31 10:43:00 peter
  106. * don't create stackframes so we can retrieve the info from
  107. the caller
  108. Revision 1.7 2004/05/30 12:08:32 florian
  109. * setjmp on sparc improved
  110. Revision 1.6 2004/05/25 21:38:11 peter
  111. * fixed input registers
  112. Revision 1.5 2004/05/18 19:36:37 florian
  113. * started to fix set/longjmp on sparc
  114. Revision 1.4 2003/01/05 21:32:35 mazen
  115. * fixing several bugs compiling the RTL
  116. Revision 1.3 2002/12/24 21:30:20 mazen
  117. - some writeln(s) removed in compiler
  118. + many files added to RTL
  119. * some errors fixed in RTL
  120. Revision 1.2 2002/11/24 18:19:44 mazen
  121. + setjmp and longjmp
  122. Revision 1.1 2002/11/16 20:10:31 florian
  123. + sparc specific rtl skeleton added
  124. }