setjump.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. procedure longjmp(var S:jmp_buf;value:longint);{assembler;}[Public,alias:'FPC_LONGJMP'];
  18. begin{asm
  19. /* Store our arguments in global registers so we can still
  20. use them while unwinding frames and their register windows. */
  21. ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */
  22. mov %o0, %g1 /* ENV in %g1 */
  23. orcc %o1, %g0, %g2 /* VAL in %g2 */
  24. be,a 0f /* Branch if zero; else skip delay slot. */
  25. mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */
  26. 0:
  27. xor %fp, %g3, %o0
  28. add %fp, 512, %o1
  29. andncc %o0, 4095, %o0
  30. bne LOC(thread)
  31. cmp %o1, %g3
  32. bl LOC(thread)
  33. /* Now we will loop, unwinding the register windows up the stack
  34. until the restored %fp value matches the target value in %g3. */
  35. LOC(loop):
  36. cmp %fp, %g3 /* Have we reached the target frame? */
  37. bl,a LOC(loop) /* Loop while current fp is below target. */
  38. restore /* Unwind register window in delay slot. */
  39. be,a LOC(found) /* Better have hit it exactly. */
  40. ld ENV(g1,JB_SP), %o0 /* Delay slot: extract target SP. */
  41. LOC(thread):
  42. /*
  43. * Do a "flush register windows trap". The trap handler in the
  44. * kernel writes all the register windows to their stack slots, and
  45. * marks them all as invalid (needing to be sucked up from the
  46. * stack when used). This ensures that all information needed to
  47. * unwind to these callers is in memory, not in the register
  48. * windows.
  49. */
  50. ta ST_FLUSH_WINDOWS
  51. ld ENV(g1,JB_PC), %o7 /* Set return PC. */
  52. ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */
  53. sub %fp, 64, %sp /* Allocate a register frame. */
  54. st %g3, RW_FP /* Set saved FP on restore below. */
  55. retl
  56. restore %g2, 0, %o0 /* Restore values from above register frame. */
  57. LOC(found):
  58. /* We have unwound register windows so %fp matches the target. */
  59. mov %o0, %sp /* OK, install new SP. */
  60. LOC(sp_ok):
  61. ld ENV(g1,JB_PC), %o0 /* Extract target return PC. */
  62. jmp %o0 + 8 /* Return there. */
  63. mov %g2, %o0 /* Delay slot: set return value. */
  64. }
  65. end;
  66. function setjmp(var S:jmp_buf):longint;{assembler;}[Public,alias:'FPC_SETJMP'];
  67. begin{asm
  68. b 1f
  69. set 0, %o1}
  70. end;
  71. {ENTRY (__sigsetjmp)
  72. 1:
  73. /* Save our PC, SP and FP. Save the signal mask if requested with
  74. a tail-call for simplicity; it always returns zero. */
  75. ta ST_FLUSH_WINDOWS
  76. st %o7, [%o0 + (JB_PC * 4)]
  77. st %sp, [%o0 + (JB_SP * 4)]
  78. st %fp, [%o0 + (JB_FP * 4)]
  79. mov %o7, %g1
  80. call __sigjmp_save
  81. mov %g1, %o7
  82. END(__sigsetjmp)
  83. /* Test if longjmp to JMPBUF would unwind the frame
  84. containing a local variable at ADDRESS. */
  85. #define _JMPBUF_UNWINDS(jmpbuf, address) \
  86. ((int) (address) < (jmpbuf)[JB_SP])
  87. }
  88. {
  89. $Log$
  90. Revision 1.4 2003-01-05 21:32:35 mazen
  91. * fixing several bugs compiling the RTL
  92. Revision 1.3 2002/12/24 21:30:20 mazen
  93. - some writeln(s) removed in compiler
  94. + many files added to RTL
  95. * some errors fixed in RTL
  96. Revision 1.2 2002/11/24 18:19:44 mazen
  97. + setjmp and longjmp
  98. Revision 1.1 2002/11/16 20:10:31 florian
  99. + sparc specific rtl skeleton added
  100. }