summaryrefslogtreecommitdiff
path: root/ports/sysdeps/hppa
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2012-11-19 00:28:30 -0500
committerCarlos O'Donell <carlos@systemhalted.org>2012-11-19 00:28:30 -0500
commit320194d5b958156a9ad21e8c4e07e8033b405ccd (patch)
treeda19acdb612dc723b93a792f83edfff42c92b2d0 /ports/sysdeps/hppa
parent05b227bdaea9a5f1faf08dad31221d8736f3659d (diff)
downloadglibc-320194d5b958156a9ad21e8c4e07e8033b405ccd.tar.gz
hppa: Implement __longjmp_chk.
Implement longjmp and the chk variant in C.
Diffstat (limited to 'ports/sysdeps/hppa')
-rw-r--r--ports/sysdeps/hppa/__longjmp.S71
-rw-r--r--ports/sysdeps/hppa/__longjmp.c83
-rw-r--r--ports/sysdeps/hppa/bits/setjmp.h39
-rw-r--r--ports/sysdeps/hppa/setjmp.S8
4 files changed, 121 insertions, 80 deletions
diff --git a/ports/sysdeps/hppa/__longjmp.S b/ports/sysdeps/hppa/__longjmp.S
deleted file mode 100644
index 4ef219e414..0000000000
--- a/ports/sysdeps/hppa/__longjmp.S
+++ /dev/null
@@ -1,71 +0,0 @@
-/* longjmp for PA-RISC.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library. If not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-#define _SETJMP_H
-#define _ASM
-#include <bits/setjmp.h>
-
-/* __longjmp(jmpbuf, val) */
-
- .text
- .align 4
- .globl __longjmp
- .export __longjmp, code
- .proc
- .callinfo
-__longjmp:
- /* set return value */
- copy %r25, %r28
-
- ldw 0(%r26), %r3
- ldw 8(%r26), %r4
- ldw 12(%r26), %r5
- ldw 16(%r26), %r6
- ldw 20(%r26), %r7
- ldw 24(%r26), %r8
- ldw 28(%r26), %r9
- ldw 32(%r26), %r10
- ldw 36(%r26), %r11
- ldw 40(%r26), %r12
- ldw 44(%r26), %r13
- ldw 48(%r26), %r14
- ldw 52(%r26), %r15
- ldw 56(%r26), %r16
- ldw 60(%r26), %r17
- ldw 64(%r26), %r18
- ldw 68(%r26), %r19
- ldw 72(%r26), %r27
- ldw 76(%r26), %r30
-
- ldw 80(%r26), %rp
-
- ldo 88(%r26),%r20
- fldds,ma 8(%r20), %fr12
- fldds,ma 8(%r20), %fr13
- fldds,ma 8(%r20), %fr14
- fldds,ma 8(%r20), %fr15
- fldds,ma 8(%r20), %fr16
- fldds,ma 8(%r20), %fr17
- fldds,ma 8(%r20), %fr18
- fldds,ma 8(%r20), %fr19
- fldds,ma 8(%r20), %fr20
- fldds 0(%r20), %fr21
-
- bv,n %r0(%r2)
- .procend
diff --git a/ports/sysdeps/hppa/__longjmp.c b/ports/sysdeps/hppa/__longjmp.c
new file mode 100644
index 0000000000..8ad51055f2
--- /dev/null
+++ b/ports/sysdeps/hppa/__longjmp.c
@@ -0,0 +1,83 @@
+/* longjmp for PA-RISC.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <setjmp.h>
+#include <stdlib.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0. */
+void
+__longjmp (__jmp_buf env, int val)
+{
+ /* We must use one of the non-callee saves registers
+ for env. */
+ register unsigned long r26 asm ("r26") = (unsigned long)&env[0];
+
+#ifdef CHECK_SP
+ CHECK_SP (env[0].__jmp_buf.__sp);
+#endif
+
+ asm volatile(
+ /* Set return value. */
+ "copy %0, %%r28\n\t"
+ /* Load callee saves from r3 to r18. */
+ "ldw 0(%1), %%r3\n\t"
+ "ldw 8(%1), %%r4\n\t"
+ "ldw 12(%1), %%r5\n\t"
+ "ldw 16(%1), %%r6\n\t"
+ "ldw 20(%1), %%r7\n\t"
+ "ldw 24(%1), %%r8\n\t"
+ "ldw 28(%1), %%r9\n\t"
+ "ldw 32(%1), %%r10\n\t"
+ "ldw 36(%1), %%r11\n\t"
+ "ldw 40(%1), %%r12\n\t"
+ "ldw 44(%1), %%r13\n\t"
+ "ldw 48(%1), %%r14\n\t"
+ "ldw 52(%1), %%r15\n\t"
+ "ldw 56(%1), %%r16\n\t"
+ "ldw 60(%1), %%r17\n\t"
+ "ldw 64(%1), %%r18\n\t"
+ /* Load PIC register. */
+ "ldw 68(%1), %%r19\n\t"
+ /* Load static link register. */
+ "ldw 72(%1), %%r27\n\t"
+ /* Load stack pointer. */
+ "ldw 76(%1), %%r30\n\t"
+ /* Load return pointer. */
+ "ldw 80(%1), %%rp\n\t"
+ /* Ues a spare caller saves register. */
+ "ldo 88(%1),%%r20\n\t"
+ /* Load callee saves from fr12 to fr21. */
+ "fldds,ma 8(%%r20), %%fr12\n\t"
+ "fldds,ma 8(%%r20), %%fr13\n\t"
+ "fldds,ma 8(%%r20), %%fr14\n\t"
+ "fldds,ma 8(%%r20), %%fr15\n\t"
+ "fldds,ma 8(%%r20), %%fr16\n\t"
+ "fldds,ma 8(%%r20), %%fr17\n\t"
+ "fldds,ma 8(%%r20), %%fr18\n\t"
+ "fldds,ma 8(%%r20), %%fr19\n\t"
+ "fldds,ma 8(%%r20), %%fr20\n\t"
+ "fldds 0(%%r20), %%fr21\n\t"
+ /* Jump back to stored return address. */
+ "bv,n %%r0(%%r2)\n\t"
+ : /* No outputs. */
+ : "r" (val == 0 ? 1 : val), "r" (r26)
+ : /* No point in clobbers. */ );
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/ports/sysdeps/hppa/bits/setjmp.h b/ports/sysdeps/hppa/bits/setjmp.h
index 19a0cfe621..7283cc16f3 100644
--- a/ports/sysdeps/hppa/bits/setjmp.h
+++ b/ports/sysdeps/hppa/bits/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -23,13 +23,38 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
-/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
- We use an array of 'double' instead, to make writing the assembler
- easier, and to ensure proper alignment. Naturally, user code should
- not depend on either representation. */
-
#ifndef _ASM
-typedef double __jmp_buf[21];
+/* The entire jump buffer must be 168 bytes long and laid
+ out in exactly as follows for ABI consistency.
+ * 20 x 32-bit gprs, with 8-bytes of padding, arranged so:
+ - r3 (callee saves)
+ - 4 bytes of padding.
+ - r4-r18 (callee saves)
+ - r19 (PIC register)
+ - r27 (static link register)
+ - r30 (stcack pointer)
+ - r2 (return pointer)
+ - 4 bytes of padding.
+ * 10 x 64-bit fprs in this order:
+ - fr12-fr21 (callee saves)
+ Note: We have 8 bytes of free space for future uses. */
+typedef union
+ {
+ struct __jmp_buf_internal_tag
+ {
+ int __r3;
+ int __pad0;
+ int __r4_r18[15];
+ int __r19;
+ int __r27;
+ int __sp;
+ int __rp;
+ int __pad1;
+ double __fr12_fr21[10];
+ } __jmp_buf;
+ /* Legacy definition. Ensures double alignment for fpsrs. */
+ double __align[21];
+ } __jmp_buf[1];
#endif
#endif /* bits/setjmp.h */
diff --git a/ports/sysdeps/hppa/setjmp.S b/ports/sysdeps/hppa/setjmp.S
index 146e4d1943..0f05fd9951 100644
--- a/ports/sysdeps/hppa/setjmp.S
+++ b/ports/sysdeps/hppa/setjmp.S
@@ -1,5 +1,5 @@
/* setjmp for HPPA.
- Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,8 @@
.callinfo
__sigsetjmp:
stw %r3, 0(%r26)
+ /* This padding exists for unknown historical reasons. */
+ /* 4 - 4 bytes of padding. */
stw %r4, 8(%r26)
stw %r5, 12(%r26)
stw %r6, 16(%r26)
@@ -51,7 +53,8 @@ __sigsetjmp:
stw %r30, 76(%r26)
stw %rp, 80(%r26)
-
+ /* This padding exists to ensure double alignment for fprs. */
+ /* 84 - 4 bytes of padding. */
ldo 88(%r26),%r1
fstds,ma %fr12, 8(%r1) /* 88 */
fstds,ma %fr13, 8(%r1) /* 96 */
@@ -63,6 +66,7 @@ __sigsetjmp:
fstds,ma %fr19, 8(%r1) /* 144 */
fstds,ma %fr20, 8(%r1) /* 152 */
fstds %fr21, 0(%r1) /* 160 */
+ /* Total of 168 bytes. */
b __sigjmp_save
nop
.procend