From b8755b6b2ce844996f61e168d08f9746c096022c Mon Sep 17 00:00:00 2001 From: florian <florian@freepascal.org> Date: Sun, 18 Jun 2017 15:41:25 +0000 Subject: [PATCH] + setjmp/longjmp implementation for sparc64, based on the sparc one git-svn-id: trunk@36513 - --- .gitattributes | 2 + rtl/sparc64/setjump.inc | 92 ++++++++++++++++++++++++++++++++++++++++ rtl/sparc64/setjumph.inc | 24 +++++++++++ 3 files changed, 118 insertions(+) create mode 100644 rtl/sparc64/setjump.inc create mode 100644 rtl/sparc64/setjumph.inc diff --git a/.gitattributes b/.gitattributes index 13b8e5fe84..084bb4ad56 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9971,6 +9971,8 @@ rtl/sparc64/int64p.inc svneol=native#text/plain rtl/sparc64/makefile.cpu svneol=native#text/plain rtl/sparc64/math.inc svneol=native#text/plain rtl/sparc64/set.inc svneol=native#text/plain +rtl/sparc64/setjump.inc svneol=native#text/plain +rtl/sparc64/setjumph.inc svneol=native#text/plain rtl/sparc64/sparc64.inc svneol=native#text/plain rtl/symbian/Makefile svneol=native#text/plain rtl/symbian/Makefile.fpc svneol=native#text/plain diff --git a/rtl/sparc64/setjump.inc b/rtl/sparc64/setjump.inc new file mode 100644 index 0000000000..62f8910e79 --- /dev/null +++ b/rtl/sparc64/setjump.inc @@ -0,0 +1,92 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2002 by Jonas Maebe and other members of the + Free Pascal development team + + SetJmp and LongJmp implementation for exception handling + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{#define ENV(base,reg) [%base + (reg * 4)] +#define ST_FLUSH_WINDOWS 3 +#define RW_FP [%fp + 0x48] +} + +procedure fpc_longjmp(var s : jmp_buf;value:longint);assembler;nostackframe;[Public,alias:'FPC_LONGJMP'];compilerproc; + asm + // Store our arguments in global registers so we can still + // use them while unwinding frames and their register windows. + + ld [%o0+4], %g3 // Cache target FP in register %g3. + mov %o0, %g1 // s in %g1 + orcc %o1, %g0, %g2 // value in %g2 + be,a .L0 // Branch if zero; else skip delay slot. + mov 1, %g2 // Delay slot only hit if zero: VAL = 1. +.L0: + xor %fp, %g3, %o0 + add %fp, 512, %o1 + andncc %o0, 4095, %o0 + bne .Lthread + cmp %o1, %g3 + bl .Lthread + + // Now we will loop, unwinding the register windows up the stack + // until the restored %fp value matches the target value in %g3. + +.Lloop: + cmp %fp, %g3 // Have we reached the target frame? + bl,a .Lloop // Loop while current fp is below target. + restore // Unwind register window in delay slot. + be,a .Lfound // Better have hit it exactly. + ld [%g1], %o0 // Delay slot: extract target SP. + +.Lthread: + { + * Do a "flush register windows trap". The trap handler in the + * kernel writes all the register windows to their stack slots, and + * marks them all as invalid (needing to be sucked up from the + * stack when used). This ensures that all information needed to + * unwind to these callers is in memory, not in the register + * windows. + } + + ta 3 + mov %g1,%o1 // use %o1, since %g1 will be destroyed by the call below + + ld [%o1], %fp // Set saved SP on restore below. + sub %fp, 64, %sp // Allocate a register frame. + st %g3, [%fp+48] // Set saved FP on restore below. + + ld [%o1+8], %o7 // Set return PC. + + retl + restore %g2, 0, %o0 // Restore values from above register frame. + +.Lfound: + // We have unwound register windows so %fp matches the target. + mov %o0, %sp // OK, install new SP. + +.Lsp_ok: + ld [%g1+8], %o0 // Extract target return PC. + jmp %o0+8 // Return there. + mov %g2, %o0 // Delay slot: set return value. + end; + + +function fpc_setjmp(var S:jmp_buf):longint;assembler;nostackframe;[Public,alias:'FPC_SETJMP'];compilerproc; + asm + // We don't create a stackframe so we can save PC,SP and FP of the caller + st %o7, [%o0+8] + st %sp, [%o0] + st %fp, [%o0+4] + + ld [%o0+8], %o7 + mov %g0, %o0 + end; + diff --git a/rtl/sparc64/setjumph.inc b/rtl/sparc64/setjumph.inc new file mode 100644 index 0000000000..3a17376399 --- /dev/null +++ b/rtl/sparc64/setjumph.inc @@ -0,0 +1,24 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1998 the Free Pascal development team + + SetJmp/Longjmp declarations + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} + +Type + jmp_buf = record + sp,fp,pc : Pointer; + end; + PJmp_buf = ^jmp_buf; + +Function Setjmp (Var S : Jmp_buf) : longint; [external name 'FPC_SETJMP']; +Procedure longjmp (Var S : Jmp_buf; value : longint); [external name 'FPC_LONGJMP']; +