diff options
Diffstat (limited to 'ports/sysdeps/unix/alpha/sysdep.S')
-rw-r--r-- | ports/sysdeps/unix/alpha/sysdep.S | 114 |
1 files changed, 23 insertions, 91 deletions
diff --git a/ports/sysdeps/unix/alpha/sysdep.S b/ports/sysdeps/unix/alpha/sysdep.S index c67a6542f..8003fdca8 100644 --- a/ports/sysdeps/unix/alpha/sysdep.S +++ b/ports/sysdeps/unix/alpha/sysdep.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1996, 1998, 2002, 2003, 2004 +/* Copyright (C) 1993, 1996, 1998, 2002, 2003, 2004, 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Brendan Kehoe (brendan@zen.org). @@ -21,7 +21,7 @@ #include <sysdep.h> #include <features.h> -#if defined(__ELF__) && defined(PIC) +#if defined(PIC) /* Put this at the end of libc's text segment so that all of the direct branches from the syscalls are forward, and thus predicted not taken. */ @@ -30,106 +30,38 @@ .text #endif -#ifdef PIC - /* When building a shared library, we branch here without - having loaded the GP. Nor, since it was a direct branch, - have we loaded PV with our address. Do both. */ -# define LOADGP br pv, 1f; 1: ldgp gp, 0(pv) -# define PROLOGUE .prologue 0 -# define EPILOGUE +#ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno #else - /* When building the static library, we tail call here from - elsewhere, which might use a different GP. The entertaining - part is that we have to return with the GP of our caller - in place, so that linker relaxation works properly. */ - /* ??? This is so ugly. Consider always putting the errno - setting code with the syscall in the static case. */ -# define GPSAVEREG t10 -# define LOADGP ldah t11, 0(pv) !gpdisp!1; \ - br 1f; \ - .subsection 2; \ - 1: mov gp, GPSAVEREG; \ - lda gp, 0(t11) !gpdisp!1; \ - br 2f; \ - .previous; \ - mov gp, GPSAVEREG; \ - 2: -# define PROLOGUE .prologue 1 -# define EPILOGUE mov GPSAVEREG, gp +# define SYSCALL_ERROR_ERRNO errno #endif .align 4 - .globl __syscall_error - .ent __syscall_error + .globl __syscall_error + .ent __syscall_error __syscall_error: + /* When building a shared library, we branch here without having + loaded the GP. Nor, since it was a direct branch, have we + loaded PV with our address. -#if defined(_LIBC_REENTRANT) && USE___THREAD - -#ifndef NOT_IN_libc -# define SYSCALL_ERROR_ERRNO __libc_errno -#else -# define SYSCALL_ERROR_ERRNO errno -#endif + When building a static library, we tail call here from another + object file, possibly with a different GP, and must return with + the GP of our caller in place so that linker relaxation works. - LOADGP - PROLOGUE + Both issues are solved by computing the GP into T1 instead of + clobbering the traditional GP register. */ + .prologue 0 mov v0, t0 + br t1, 1f +1: ldah t1, 0(t1) !gpdisp!1 call_pal PAL_rduniq - ldq t1, SYSCALL_ERROR_ERRNO(gp) !gottprel - addq v0, t1, v0 - stl t0, 0(v0) - lda v0, -1 - EPILOGUE - ret - -#elif defined(_LIBC_REENTRANT) - - LOADGP - lda sp, -32(sp) - .frame sp, 32, ra, 0 - stq ra, 0(sp) - stq v0, 8(sp) -#ifdef GPSAVEREG - stq GPSAVEREG, 16(sp) -#endif - .mask 0x4000001, -32 - PROLOGUE - /* Find our per-thread errno address */ -#if defined PIC && !defined IS_IN_librt - bsr ra, __errno_location !samegp -#else - jsr ra, __errno_location -#ifndef GPSAVEREG - ldgp gp, 0(ra) -#endif -#endif - - /* Store the error value. */ - ldq t0, 8(sp) - stl t0, 0(v0) - - /* And kick back a -1. */ - ldi v0, -1 - -#ifdef GPSAVEREG - ldq GPSAVEREG, 16(sp) -#endif - ldq ra, 0(sp) - lda sp, 32(sp) - EPILOGUE - ret - -#else - - LOADGP - PROLOGUE - stl v0, errno + lda t1, 0(t1) !gpdisp!1 + ldq t1, SYSCALL_ERROR_ERRNO(t1) !gottprel + addq v0, t1, t1 lda v0, -1 - EPILOGUE - ret -#endif + stl t0, 0(t1) + ret - .subsection 3 .end __syscall_error |