2ad7600be7
I've moved the MIPS port from ports to the main sysdeps hierarchy. Beyond the README update, the move of the files was simply git mv ports/sysdeps/mips sysdeps/mips git mv ports/sysdeps/unix/mips sysdeps/unix/mips git mv ports/sysdeps/unix/sysv/linux/mips sysdeps/unix/sysv/linux/mips and in addition to the ChangeLog entries here, I put a note at the top of ports/ChangeLog.mips similar to those in other files. Tested that disassembly of installed shared libraries for mips is the same before and after this patch (except for ld.so where paths in assertions are involved, as for arm). * sysdeps/mips: Move directory from ports/sysdeps/mips. * sysdeps/unix/mips: Move directory from ports/sysdeps/unix/mips. * sysdeps/unix/sysv/linux/mips: Move directory from ports/sysdeps/unix/sysv/linux/mips. * README: Update listing for mips-*-linux-gnu and mips64-*-linux-gnu. * sysdeps/mips: Move directory to ../sysdeps/mips. * sysdeps/unix/mips: Move directory to ../sysdeps/unix/mips. * sysdeps/unix/sysv/linux/mips: Move directory to ../sysdeps/unix/sysv/linux/mips.
191 lines
6.4 KiB
C
191 lines
6.4 KiB
C
/* Copyright (C) 2003-2014 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>
|
|
#include <sysdeps/generic/sysdep.h>
|
|
#include <tls.h>
|
|
#ifndef __ASSEMBLER__
|
|
# include <nptl/pthreadP.h>
|
|
#endif
|
|
|
|
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
|
|
|
|
# ifdef __PIC__
|
|
# define PSEUDO_CPLOAD .cpload t9;
|
|
# define PSEUDO_ERRJMP la t9, __syscall_error; jr t9;
|
|
# define PSEUDO_SAVEGP sw gp, 32(sp); cfi_rel_offset (gp, 32);
|
|
# define PSEUDO_LOADGP lw gp, 32(sp);
|
|
# else
|
|
# define PSEUDO_CPLOAD
|
|
# define PSEUDO_ERRJMP j __syscall_error;
|
|
# define PSEUDO_SAVEGP
|
|
# define PSEUDO_LOADGP
|
|
# endif
|
|
|
|
# undef PSEUDO
|
|
# define PSEUDO(name, syscall_name, args) \
|
|
.align 2; \
|
|
.set nomips16; \
|
|
L(pseudo_start): \
|
|
cfi_startproc; \
|
|
99: PSEUDO_ERRJMP \
|
|
.type __##syscall_name##_nocancel, @function; \
|
|
.globl __##syscall_name##_nocancel; \
|
|
__##syscall_name##_nocancel: \
|
|
.set noreorder; \
|
|
PSEUDO_CPLOAD \
|
|
li v0, SYS_ify(syscall_name); \
|
|
syscall; \
|
|
.set reorder; \
|
|
bne a3, zero, 99b; \
|
|
ret; \
|
|
cfi_endproc; \
|
|
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
|
ENTRY (name) \
|
|
.set noreorder; \
|
|
PSEUDO_CPLOAD \
|
|
.set reorder; \
|
|
SINGLE_THREAD_P(v1); \
|
|
bne zero, v1, L(pseudo_cancel); \
|
|
.set noreorder; \
|
|
li v0, SYS_ify(syscall_name); \
|
|
syscall; \
|
|
.set reorder; \
|
|
bne a3, zero, 99b; \
|
|
ret; \
|
|
L(pseudo_cancel): \
|
|
SAVESTK_##args; \
|
|
sw ra, 28(sp); \
|
|
cfi_rel_offset (ra, 28); \
|
|
PSEUDO_SAVEGP \
|
|
PUSHARGS_##args; /* save syscall args */ \
|
|
CENABLE; \
|
|
PSEUDO_LOADGP \
|
|
sw v0, 44(sp); /* save mask */ \
|
|
POPARGS_##args; /* restore syscall args */ \
|
|
.set noreorder; \
|
|
li v0, SYS_ify (syscall_name); \
|
|
syscall; \
|
|
.set reorder; \
|
|
sw v0, 36(sp); /* save syscall result */ \
|
|
sw a3, 40(sp); /* save syscall error flag */ \
|
|
lw a0, 44(sp); /* pass mask as arg1 */ \
|
|
CDISABLE; \
|
|
PSEUDO_LOADGP \
|
|
lw v0, 36(sp); /* restore syscall result */ \
|
|
lw a3, 40(sp); /* restore syscall error flag */ \
|
|
lw ra, 28(sp); /* restore return address */ \
|
|
.set noreorder; \
|
|
bne a3, zero, 99b; \
|
|
RESTORESTK; \
|
|
L(pseudo_end): \
|
|
.set reorder;
|
|
|
|
# undef PSEUDO_END
|
|
# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
|
|
|
|
# define PUSHARGS_0 /* nothing to do */
|
|
# define PUSHARGS_1 PUSHARGS_0 sw a0, 0(sp); cfi_rel_offset (a0, 0);
|
|
# define PUSHARGS_2 PUSHARGS_1 sw a1, 4(sp); cfi_rel_offset (a1, 4);
|
|
# define PUSHARGS_3 PUSHARGS_2 sw a2, 8(sp); cfi_rel_offset (a2, 8);
|
|
# define PUSHARGS_4 PUSHARGS_3 sw a3, 12(sp); cfi_rel_offset (a3, 12);
|
|
# define PUSHARGS_5 PUSHARGS_4 /* handled by SAVESTK_## */
|
|
# define PUSHARGS_6 PUSHARGS_5
|
|
# define PUSHARGS_7 PUSHARGS_6
|
|
|
|
# define POPARGS_0 /* nothing to do */
|
|
# define POPARGS_1 POPARGS_0 lw a0, 0(sp);
|
|
# define POPARGS_2 POPARGS_1 lw a1, 4(sp);
|
|
# define POPARGS_3 POPARGS_2 lw a2, 8(sp);
|
|
# define POPARGS_4 POPARGS_3 lw a3, 12(sp);
|
|
# define POPARGS_5 POPARGS_4 /* args already in new stackframe */
|
|
# define POPARGS_6 POPARGS_5
|
|
# define POPARGS_7 POPARGS_6
|
|
|
|
|
|
# define STKSPACE 48
|
|
# define SAVESTK_0 subu sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
|
|
# define SAVESTK_1 SAVESTK_0
|
|
# define SAVESTK_2 SAVESTK_1
|
|
# define SAVESTK_3 SAVESTK_2
|
|
# define SAVESTK_4 SAVESTK_3
|
|
# define SAVESTK_5 lw t0, 16(sp); \
|
|
SAVESTK_0; \
|
|
sw t0, 16(sp)
|
|
|
|
# define SAVESTK_6 lw t0, 16(sp); \
|
|
lw t1, 20(sp); \
|
|
SAVESTK_0; \
|
|
sw t0, 16(sp); \
|
|
sw t1, 20(sp)
|
|
|
|
# define SAVESTK_7 lw t0, 16(sp); \
|
|
lw t1, 20(sp); \
|
|
lw t2, 24(sp); \
|
|
SAVESTK_0; \
|
|
sw t0, 16(sp); \
|
|
sw t1, 20(sp); \
|
|
sw t2, 24(sp)
|
|
|
|
# define RESTORESTK addu sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
|
|
|
|
|
|
# ifdef __PIC__
|
|
/* We use jalr rather than jal. This means that the assembler will not
|
|
automatically restore $gp (in case libc has multiple GOTs) so we must
|
|
do it manually - which we have to do anyway since we don't use .cprestore.
|
|
It also shuts up the assembler warning about not using .cprestore. */
|
|
# define PSEUDO_JMP(sym) la t9, sym; jalr t9;
|
|
# else
|
|
# define PSEUDO_JMP(sym) jal sym;
|
|
# endif
|
|
|
|
# ifdef IS_IN_libpthread
|
|
# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
|
|
# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
|
|
# elif defined IS_IN_librt
|
|
# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
|
|
# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
|
|
# else
|
|
# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
|
|
# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
|
|
# endif
|
|
|
|
# ifndef __ASSEMBLER__
|
|
# define SINGLE_THREAD_P \
|
|
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
|
header.multiple_threads) \
|
|
== 0, 1)
|
|
# else
|
|
# define SINGLE_THREAD_P(reg) \
|
|
READ_THREAD_POINTER(reg); \
|
|
lw reg, MULTIPLE_THREADS_OFFSET(reg)
|
|
#endif
|
|
|
|
#elif !defined __ASSEMBLER__
|
|
|
|
# define SINGLE_THREAD_P 1
|
|
# define NO_CANCELLATION 1
|
|
|
|
#endif
|
|
|
|
#ifndef __ASSEMBLER__
|
|
# define RTLD_SINGLE_THREAD_P \
|
|
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
|
header.multiple_threads) == 0, 1)
|
|
#endif
|