mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 03:10:05 +00:00
Add support for building as MIPS16 code.
This commit is contained in:
parent
85bd816a60
commit
43301bd3c2
@ -1,3 +1,109 @@
|
||||
2013-02-27 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
Maciej W. Rozycki <macro@codesourcery.com>
|
||||
Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* sysdeps/mips/abort-instr.h (ABORT_INSTRUCTION) [__mips16]:
|
||||
New macro.
|
||||
* sysdeps/mips/dl-machine.h (elf_machine_load_address): Add
|
||||
MIPS16 version of assembly code.
|
||||
(RTLD_START) [__mips16]: New macro.
|
||||
* sysdeps/mips/fpu_control.h (__mips_fpu_getcw): New prototype.
|
||||
(__mips_fpu_setcw): Likewise.
|
||||
(_FPU_GETCW) [__mips16]: New macro.
|
||||
(_FPU_SETCW) [__mips16]: Likewise.
|
||||
* sysdeps/mips/machine-gmon.h (MCOUNT): Add `.set nomips16'.
|
||||
* sysdeps/mips/tls-macros.h (LOAD_GP) [__mips16]: New macro.
|
||||
(TLS_GD, TLS_LD, TLS_IE, TLS_LE) [__mips16]: Likewise.
|
||||
* sysdeps/mips/bits/atomic.h: Also use __atomic_* builtins with
|
||||
GCC 4.7 in MIPS16 code.
|
||||
(atomic_compare_and_exchange_val_acq) [__mips16]: New macro.
|
||||
(atomic_compare_and_exchange_bool_acq) [__mips16]: Likewise.
|
||||
(atomic_exchange_acq) [__mips16]: Likewise.
|
||||
(atomic_exchange_and_add) [__mips16]: Likewise.
|
||||
(atomic_bit_test_set) [__mips16]: Likewise.
|
||||
(atomic_and, atomic_and_val) [__mips16]: Likewise.
|
||||
(atomic_or, atomic_or_val) [__mips16]: Likewise.
|
||||
(atomic_full_barrier) [__mips16]: Likewise.
|
||||
* sysdeps/mips/nptl/tls.h (READ_THREAD_POINTER) [__mips16]:
|
||||
Likewise.
|
||||
* sysdeps/mips/sys/tas.h (_test_and_set): Add `__nomips16__'
|
||||
attribute.
|
||||
* sysdeps/unix/mips/sysdep.h (PSEUDO_NOERRNO): Add
|
||||
`.set nomips16'.
|
||||
(PSEUDO_ERRVAL): Likewise.
|
||||
* sysdeps/unix/mips/mips32/sysdep.h (PSEUDO): Likewise.
|
||||
* sysdeps/unix/mips/mips64/n32/sysdep.h (PSEUDO): Likewise.
|
||||
* sysdeps/unix/mips/mips64/n64/sysdep.h (PSEUDO): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
|
||||
(INTERNAL_SYSCALL, INTERNAL_SYSCALL_NCS) [__mips16]: New macros.
|
||||
(INTERNAL_SYSCALL_MIPS16) [__mips16]: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h (PSEUDO):
|
||||
Add `.set nomips16'.
|
||||
* sysdeps/mips/bsd-_setjmp.S (_setjmp): Likewise.
|
||||
* sysdeps/mips/bsd-setjmp.S (setjmp): Likewise.
|
||||
* sysdeps/mips/memset.S (memset): Likewise.
|
||||
* sysdeps/mips/setjmp.S (__sigsetjmp): Likewise.
|
||||
* sysdeps/mips/start.S (ENTRY_POINT) [__mips16]: New function.
|
||||
* sysdeps/mips/mips32/crti.S: Add `.set nomips16'.
|
||||
* sysdeps/mips/mips32/crtn.S: Likewise.
|
||||
* sysdeps/mips/mips64/n32/crti.S: Likewise.
|
||||
* sysdeps/mips/mips64/n32/crtn.S: Likewise.
|
||||
* sysdeps/mips/mips64/n64/crti.S: Likewise.
|
||||
* sysdeps/mips/mips64/n64/crtn.S: Likewise.
|
||||
* sysdeps/unix/mips/sysdep.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/clone.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/getcontext.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/makecontext.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/setcontext.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/swapcontext.S: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/vfork.S: Likewise.
|
||||
* sysdeps/mips/__longjmp.c (__longjmp): Rename function to...
|
||||
(____longjmp): ... this. Make static and add `nomips16'
|
||||
attribute.
|
||||
(__longjmp): New alias.
|
||||
* sysdeps/mips/dl-trampoline.c (_dl_runtime_resolve) [__mips16]:
|
||||
New function.
|
||||
(_dl_runtime_pltresolve): Likewise.
|
||||
* sysdeps/mips/setjmp_aux.c (__sigsetjmp_aux): Add `nomips16'
|
||||
attribute.
|
||||
* sysdeps/mips/fpu/e_sqrt.c (__ieee754_sqrt): Likewise.
|
||||
* sysdeps/mips/fpu/e_sqrtf.c (__ieee754_sqrtf): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/brk.c (__brk): Rewrite in terms
|
||||
of INTERNAL_SYSCALL.
|
||||
* sysdeps/mips/mips32/fpu/fpu_control.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/add_n.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/addmul_1.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/lshift.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/mul_1.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/rshift.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/sub_n.c: New file.
|
||||
* sysdeps/mips/mips32/mips16/submul_1.c: New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c:
|
||||
New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c:
|
||||
New file.
|
||||
* sysdeps/mips/mips32/fpu/Versions: New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions: New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist: New
|
||||
file.
|
||||
* sysdeps/mips/mips32/mips16/fpu/Makefile: New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile: New file.
|
||||
* sysdeps/mips/preconfigure: Handle o32 MIPS16 compilation.
|
||||
|
||||
2013-02-20 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
* sysdeps/mips/bits/nan.h [!__GNUC__] (__nan_union): Change
|
||||
|
@ -23,8 +23,8 @@
|
||||
#error This file uses GNU C extensions; you must compile with GCC.
|
||||
#endif
|
||||
|
||||
void
|
||||
__longjmp (env_arg, val_arg)
|
||||
static void __attribute__ ((nomips16))
|
||||
____longjmp (env_arg, val_arg)
|
||||
__jmp_buf env_arg;
|
||||
int val_arg;
|
||||
{
|
||||
@ -86,3 +86,5 @@ __longjmp (env_arg, val_arg)
|
||||
/* Avoid `volatile function does return' warnings. */
|
||||
for (;;);
|
||||
}
|
||||
|
||||
strong_alias (____longjmp, __longjmp);
|
||||
|
@ -1,2 +1,6 @@
|
||||
/* An instruction which should crash any program is a breakpoint. */
|
||||
#define ABORT_INSTRUCTION asm ("break 255")
|
||||
#ifdef __mips16
|
||||
# define ABORT_INSTRUCTION asm ("break 63")
|
||||
#else
|
||||
# define ABORT_INSTRUCTION asm ("break 255")
|
||||
#endif
|
||||
|
@ -78,9 +78,12 @@ typedef uintmax_t uatomic_max_t;
|
||||
#define MIPS_SYNC_STR_1(X) MIPS_SYNC_STR_2(X)
|
||||
#define MIPS_SYNC_STR MIPS_SYNC_STR_1(MIPS_SYNC)
|
||||
|
||||
#if __GNUC_PREREQ (4, 8)
|
||||
#if __GNUC_PREREQ (4, 8) || (defined __mips16 && __GNUC_PREREQ (4, 7))
|
||||
/* The __atomic_* builtins are available in GCC 4.7 and later, but MIPS
|
||||
support for their efficient implementation was added only in GCC 4.8. */
|
||||
support for their efficient implementation was added only in GCC 4.8.
|
||||
We still want to use them even with GCC 4.7 for MIPS16 code where we
|
||||
have no assembly alternative available and want to avoid the __sync_*
|
||||
if at all possible. */
|
||||
|
||||
/* Compare and exchange.
|
||||
For all "bool" routines, we return FALSE if exchange succesful. */
|
||||
@ -200,7 +203,33 @@ typedef uintmax_t uatomic_max_t;
|
||||
# define atomic_exchange_and_add_rel(mem, value) \
|
||||
__atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
|
||||
__ATOMIC_RELEASE)
|
||||
#else /* !__GNUC_PREREQ (4, 8) */
|
||||
|
||||
#elif defined __mips16 /* !__GNUC_PREREQ (4, 7) */
|
||||
/* This implementation using __sync* builtins will be removed once glibc
|
||||
requires GCC 4.7 or later to build. */
|
||||
|
||||
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
__sync_val_compare_and_swap ((mem), (oldval), (newval))
|
||||
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
(!__sync_bool_compare_and_swap ((mem), (oldval), (newval)))
|
||||
|
||||
# define atomic_exchange_acq(mem, newval) \
|
||||
__sync_lock_test_and_set ((mem), (newval))
|
||||
|
||||
# define atomic_exchange_and_add(mem, val) \
|
||||
__sync_fetch_and_add ((mem), (val))
|
||||
|
||||
# define atomic_bit_test_set(mem, bit) \
|
||||
({ __typeof (bit) __bit = (bit); \
|
||||
(__sync_fetch_and_or ((mem), 1 << (__bit)) & (1 << (__bit))); })
|
||||
|
||||
# define atomic_and(mem, mask) (void) __sync_fetch_and_and ((mem), (mask))
|
||||
# define atomic_and_val(mem, mask) __sync_fetch_and_and ((mem), (mask))
|
||||
|
||||
# define atomic_or(mem, mask) (void) __sync_fetch_and_or ((mem), (mask))
|
||||
# define atomic_or_val(mem, mask) __sync_fetch_and_or ((mem), (mask))
|
||||
|
||||
#else /* !__mips16 && !__GNUC_PREREQ (4, 8) */
|
||||
/* This implementation using inline assembly will be removed once glibc
|
||||
requires GCC 4.8 or later to build. */
|
||||
|
||||
@ -443,15 +472,21 @@ typedef uintmax_t uatomic_max_t;
|
||||
# define atomic_exchange_and_add_rel(mem, value) \
|
||||
__atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
|
||||
MIPS_SYNC_STR, "")
|
||||
#endif /* __GNUC_PREREQ (4, 8) */
|
||||
|
||||
#endif /* !__mips16 && !__GNUC_PREREQ (4, 8) */
|
||||
|
||||
/* TODO: More atomic operations could be implemented efficiently; only the
|
||||
basic requirements are done. */
|
||||
|
||||
#define atomic_full_barrier() \
|
||||
#ifdef __mips16
|
||||
# define atomic_full_barrier() __sync_synchronize ()
|
||||
|
||||
#else /* !__mips16 */
|
||||
# define atomic_full_barrier() \
|
||||
__asm__ __volatile__ (".set push\n\t" \
|
||||
MIPS_PUSH_MIPS2 \
|
||||
MIPS_SYNC_STR "\n\t" \
|
||||
".set pop" : : : "memory")
|
||||
#endif /* !__mips16 */
|
||||
|
||||
#endif /* bits/atomic.h */
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.set nomips16
|
||||
|
||||
#ifdef __PIC__
|
||||
.option pic2
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.set nomips16
|
||||
|
||||
#ifdef __PIC__
|
||||
.option pic2
|
||||
#endif
|
||||
|
@ -119,6 +119,7 @@ static inline ElfW(Addr)
|
||||
elf_machine_load_address (void)
|
||||
{
|
||||
ElfW(Addr) addr;
|
||||
#ifndef __mips16
|
||||
asm (" .set noreorder\n"
|
||||
" " STRINGXP (PTR_LA) " %0, 0f\n"
|
||||
" bltzal $0, 0f\n"
|
||||
@ -128,6 +129,19 @@ elf_machine_load_address (void)
|
||||
: "=r" (addr)
|
||||
: /* No inputs */
|
||||
: "$31");
|
||||
#else
|
||||
ElfW(Addr) tmp;
|
||||
asm (" .set noreorder\n"
|
||||
" move %1,$gp\n"
|
||||
" lw %1,%%got(0f)(%1)\n"
|
||||
"0: .fill 0\n" /* Clear the ISA bit on 0:. */
|
||||
" la %0,0b\n"
|
||||
" addiu %1,%%lo(0b)\n"
|
||||
" subu %0,%1\n"
|
||||
" .set reorder\n"
|
||||
: "=d" (addr), "=d" (tmp)
|
||||
: /* No inputs */);
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -210,7 +224,8 @@ do { \
|
||||
2) That under Unix the entry is named __start
|
||||
and not just plain _start. */
|
||||
|
||||
#define RTLD_START asm (\
|
||||
#ifndef __mips16
|
||||
# define RTLD_START asm (\
|
||||
".text\n\
|
||||
" _RTLD_PROLOGUE(ENTRY_POINT) "\
|
||||
" STRINGXV(SETUP_GPX($25)) "\n\
|
||||
@ -283,6 +298,91 @@ do { \
|
||||
".previous"\
|
||||
);
|
||||
|
||||
#else /* __mips16 */
|
||||
/* MIPS16 version. We currently only support O32 under MIPS16; the proper
|
||||
assembly preprocessor abstractions will need to be added if other ABIs
|
||||
are to be supported. */
|
||||
|
||||
# define RTLD_START asm (\
|
||||
".text\n\
|
||||
.set mips16\n\
|
||||
" _RTLD_PROLOGUE (ENTRY_POINT) "\
|
||||
# Construct GP value in $3.\n\
|
||||
li $3, %hi(_gp_disp)\n\
|
||||
addiu $4, $pc, %lo(_gp_disp)\n\
|
||||
sll $3, 16\n\
|
||||
addu $3, $4\n\
|
||||
move $28, $3\n\
|
||||
lw $4, %got(_DYNAMIC)($3)\n\
|
||||
sw $4, -0x7ff0($3)\n\
|
||||
move $4, $sp\n\
|
||||
addiu $sp, -16\n\
|
||||
# _dl_start() is sufficiently near to use pc-relative\n\
|
||||
# load address.\n\
|
||||
la $3, _dl_start\n\
|
||||
move $25, $3\n\
|
||||
jalr $3\n\
|
||||
addiu $sp, 16\n\
|
||||
" _RTLD_EPILOGUE (ENTRY_POINT) "\
|
||||
\n\
|
||||
\n\
|
||||
" _RTLD_PROLOGUE (_dl_start_user) "\
|
||||
li $16, %hi(_gp_disp)\n\
|
||||
addiu $4, $pc, %lo(_gp_disp)\n\
|
||||
sll $16, 16\n\
|
||||
addu $16, $4\n\
|
||||
move $17, $2\n\
|
||||
move $28, $16\n\
|
||||
lw $4, %got(_dl_skip_args)($16)\n\
|
||||
lw $4, 0($4)\n\
|
||||
beqz $4, 1f\n\
|
||||
# Load the original argument count.\n\
|
||||
lw $5, 0($sp)\n\
|
||||
# Subtract _dl_skip_args from it.\n\
|
||||
subu $5, $4\n\
|
||||
# Adjust the stack pointer to skip _dl_skip_args words.\n\
|
||||
sll $4, " STRINGXP (PTRLOG) "\n\
|
||||
move $6, $sp\n\
|
||||
addu $6, $4\n\
|
||||
move $sp, $6\n\
|
||||
# Save back the modified argument count.\n\
|
||||
sw $5, 0($sp)\n\
|
||||
1: # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\
|
||||
lw $4, %got(_rtld_local)($16)\n\
|
||||
lw $4, 0($4)\n\
|
||||
lw $5, 0($sp)\n\
|
||||
addiu $6, $sp, " STRINGXP (PTRSIZE) "\n\
|
||||
sll $7, $5, " STRINGXP (PTRLOG) "\n\
|
||||
addu $7, $6\n\
|
||||
addu $7, " STRINGXP (PTRSIZE) "\n\
|
||||
# Make sure the stack pointer is aligned for _dl_init_internal.\n\
|
||||
li $2, 2 * " STRINGXP (SZREG) "\n\
|
||||
neg $2, $2\n\
|
||||
move $3, $sp\n\
|
||||
and $2, $3\n\
|
||||
sw $3, -" STRINGXP (SZREG) "($2)\n\
|
||||
addiu $2, -32\n\
|
||||
move $sp, $2\n\
|
||||
sw $16, 16($sp)\n\
|
||||
# Call the function to run the initializers.\n\
|
||||
lw $2, %call16(_dl_init_internal)($16)\n\
|
||||
move $25, $2\n\
|
||||
jalr $2\n\
|
||||
# Restore the stack pointer for _start.\n\
|
||||
lw $2, 32-" STRINGXP (SZREG) "($sp)\n\
|
||||
move $sp, $2\n\
|
||||
move $28, $16\n\
|
||||
# Pass our finalizer function to the user in $2 as per ELF ABI.\n\
|
||||
lw $2, %call16(_dl_fini)($16)\n\
|
||||
# Jump to the user entry point.\n\
|
||||
move $25, $17\n\
|
||||
jr $17\n\t"\
|
||||
_RTLD_EPILOGUE (_dl_start_user)\
|
||||
".previous"\
|
||||
);
|
||||
|
||||
#endif /* __mips16 */
|
||||
|
||||
/* Names of the architecture-specific auditing callback functions. */
|
||||
# if _MIPS_SIM == _ABIO32
|
||||
# define ARCH_LA_PLTENTER mips_o32_gnu_pltenter
|
||||
|
@ -292,9 +292,11 @@ __dl_runtime_resolve (ElfW(Word) sym_index,
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __mips16
|
||||
asm ("\n\
|
||||
.text\n\
|
||||
.align 2\n\
|
||||
.set nomips16\n\
|
||||
.globl _dl_runtime_resolve\n\
|
||||
.type _dl_runtime_resolve,@function\n\
|
||||
.ent _dl_runtime_resolve\n\
|
||||
@ -351,6 +353,7 @@ _dl_runtime_resolve:\n\
|
||||
asm ("\n\
|
||||
.text\n\
|
||||
.align 2\n\
|
||||
.set nomips16\n\
|
||||
.globl _dl_runtime_pltresolve\n\
|
||||
.type _dl_runtime_pltresolve,@function\n\
|
||||
.ent _dl_runtime_pltresolve\n\
|
||||
@ -381,3 +384,130 @@ _dl_runtime_pltresolve:\n\
|
||||
.previous\n\
|
||||
");
|
||||
|
||||
#elif _MIPS_SIM == _ABIO32 /* __mips16 */
|
||||
/* MIPS16 version, O32 only. */
|
||||
asm ("\n\
|
||||
.text\n\
|
||||
.align 2\n\
|
||||
.set mips16\n\
|
||||
.globl _dl_runtime_resolve\n\
|
||||
.type _dl_runtime_resolve,@function\n\
|
||||
.ent _dl_runtime_resolve\n\
|
||||
_dl_runtime_resolve:\n\
|
||||
.frame $29, " STRINGXP (ELF_DL_FRAME_SIZE) ", $31\n\
|
||||
# Save arguments and sp value in stack.\n\t"
|
||||
# if _MIPS_ISA >= _MIPS_ISA_MIPS32
|
||||
"save " STRINGXP (ELF_DL_FRAME_SIZE) ", $4-$7, $ra\n\t"
|
||||
# else
|
||||
"addiu $sp, -" STRINGXP (ELF_DL_FRAME_SIZE) "\n\
|
||||
sw $7, 32($sp)\n\
|
||||
sw $6, 28($sp)\n\
|
||||
sw $5, 24($sp)\n\
|
||||
sw $4, 20($sp)\n\t"
|
||||
# endif
|
||||
"# Preserve caller's $ra, for RESTORE instruction below.\n\
|
||||
move $5, $15\n\
|
||||
sw $5, 36($sp)\n\
|
||||
# Compute GP into $2.\n\
|
||||
li $2, %hi(_gp_disp)\n\
|
||||
addiu $3, $pc, %lo(_gp_disp)\n\
|
||||
sll $2, 16\n\
|
||||
addu $2, $3\n\
|
||||
lw $3, %got(__dl_runtime_resolve)($2)\n\
|
||||
move $4, $24\n\
|
||||
addiu $3, %lo(__dl_runtime_resolve)\n\
|
||||
move $7, $ra\n\
|
||||
move $6, $28\n\
|
||||
move $25, $3\n\
|
||||
jalr $3\n\t"
|
||||
# if _MIPS_ISA >= _MIPS_ISA_MIPS32
|
||||
"restore " STRINGXP(ELF_DL_FRAME_SIZE) ", $4-$7, $ra\n\t"
|
||||
# else
|
||||
"# Restore $ra, move placed further down to hide latency.\n\
|
||||
lw $4, 36($sp)\n\
|
||||
lw $5, 24($sp)\n\
|
||||
lw $6, 28($sp)\n\
|
||||
lw $7, 32($sp)\n\
|
||||
move $ra, $4\n\
|
||||
lw $4, 20($sp)\n\
|
||||
addiu $sp, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\t"
|
||||
# endif
|
||||
"move $25, $2\n\
|
||||
jr $2\n\
|
||||
.end _dl_runtime_resolve\n\
|
||||
.previous\n\
|
||||
");
|
||||
|
||||
asm ("\n\
|
||||
.text\n\
|
||||
.align 2\n\
|
||||
.set mips16\n\
|
||||
.globl _dl_runtime_pltresolve\n\
|
||||
.type _dl_runtime_pltresolve,@function\n\
|
||||
.ent _dl_runtime_pltresolve\n\
|
||||
_dl_runtime_pltresolve:\n\
|
||||
.frame $29, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) ", $31\n\
|
||||
# Save arguments and sp value in stack.\n\t"
|
||||
# if _MIPS_ISA >= _MIPS_ISA_MIPS32
|
||||
"save " STRINGXP(ELF_DL_PLT_FRAME_SIZE) ", $4-$7, $ra\n\t"
|
||||
# else
|
||||
"addiu $sp, -" STRINGXP(ELF_DL_PLT_FRAME_SIZE) "\n\
|
||||
sw $7, 40($sp)\n\
|
||||
sw $6, 36($sp)\n\
|
||||
sw $5, 32($sp)\n\
|
||||
sw $4, 28($sp)\n\t"
|
||||
# endif
|
||||
"# Preserve MIPS16 stub function arguments.\n\
|
||||
sw $3, 20($sp)\n\
|
||||
sw $2, 16($sp)\n\
|
||||
# Preserve caller's $ra, for RESTORE instruction below.\n\
|
||||
move $3, $15\n\
|
||||
sw $3, 44($sp)\n\
|
||||
# Compute GP into $2.\n\
|
||||
li $2, %hi(_gp_disp)\n\
|
||||
addiu $3, $pc, %lo(_gp_disp)\n\
|
||||
sll $2, 16\n\
|
||||
addu $2, $3\n\
|
||||
# Save GP value in slot.\n\
|
||||
sw $2, 24($sp)\n\
|
||||
# Load _dl_fixup address.\n\
|
||||
lw $6, %call16(_dl_fixup)($2)\n\
|
||||
# Load link map address.\n\
|
||||
move $3, $28\n\
|
||||
lw $4, " STRINGXP (PTRSIZE) "($3)\n\
|
||||
move $5, $24\n\
|
||||
sll $5, " STRINGXP (PTRLOG) " + 1\n\
|
||||
# Call _dl_fixup.\n\
|
||||
move $25, $6\n\
|
||||
jalr $6\n\
|
||||
move $25, $2\n\
|
||||
# Reload GP value into $28.\n\
|
||||
lw $3, 24($sp)\n\
|
||||
move $28, $3\n\
|
||||
lw $3, 16($sp)\n\
|
||||
move $15, $3\n\
|
||||
lw $3, 20($sp)\n\t"
|
||||
# if _MIPS_ISA >= _MIPS_ISA_MIPS32
|
||||
"restore " STRINGXP (ELF_DL_PLT_FRAME_SIZE) ", $4-$7, $ra\n\t"
|
||||
# else
|
||||
"# Restore $ra, move placed further down to hide latency.\n\
|
||||
lw $4, 44($sp)\n\
|
||||
lw $5, 32($sp)\n\
|
||||
lw $6, 36($sp)\n\
|
||||
lw $7, 40($sp)\n\
|
||||
move $ra, $4\n\
|
||||
lw $4, 28($sp)\n\
|
||||
addiu $sp, " STRINGXP (ELF_DL_PLT_FRAME_SIZE) "\n\t"
|
||||
# endif
|
||||
".set noreorder\n\
|
||||
jr $2\n\
|
||||
move $2, $15\n\
|
||||
.set reorder\n\
|
||||
.end _dl_runtime_pltresolve\n\
|
||||
.previous\n\
|
||||
");
|
||||
|
||||
#else /* __mips16 && _MIPS_SIM != _ABIO32 */
|
||||
# error "MIPS16 support for N32/N64 not implemented"
|
||||
|
||||
#endif /* __mips16 */
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
|
||||
|
||||
double
|
||||
double __attribute__ ((nomips16))
|
||||
__ieee754_sqrt (double x)
|
||||
{
|
||||
double z;
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
|
||||
|
||||
float
|
||||
float __attribute__ ((nomips16))
|
||||
__ieee754_sqrtf (float x)
|
||||
{
|
||||
float z;
|
||||
|
@ -99,8 +99,15 @@ extern fpu_control_t __fpu_control;
|
||||
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
|
||||
|
||||
/* Macros for accessing the hardware control word. */
|
||||
#define _FPU_GETCW(cw) __asm__ volatile ("cfc1 %0,$31" : "=r" (cw))
|
||||
#define _FPU_SETCW(cw) __asm__ volatile ("ctc1 %0,$31" : : "r" (cw))
|
||||
extern fpu_control_t __mips_fpu_getcw (void) __THROW;
|
||||
extern void __mips_fpu_setcw (fpu_control_t) __THROW;
|
||||
#ifdef __mips16
|
||||
# define _FPU_GETCW(cw) do { (cw) = __mips_fpu_getcw (); } while (0)
|
||||
# define _FPU_SETCW(cw) __mips_fpu_setcw (cw)
|
||||
#else
|
||||
# define _FPU_GETCW(cw) __asm__ volatile ("cfc1 %0,$31" : "=r" (cw))
|
||||
# define _FPU_SETCW(cw) __asm__ volatile ("ctc1 %0,$31" : : "r" (cw))
|
||||
#endif
|
||||
|
||||
/* Default control word set at startup. */
|
||||
extern fpu_control_t __fpu_control;
|
||||
|
@ -37,6 +37,8 @@ static void __attribute_used__ __mcount (u_long frompc, u_long selfpc)
|
||||
#define MCOUNT asm(\
|
||||
".globl _mcount;\n\t" \
|
||||
".align 2;\n\t" \
|
||||
".set push;\n\t" \
|
||||
".set nomips16;\n\t" \
|
||||
".type _mcount,@function;\n\t" \
|
||||
".ent _mcount\n\t" \
|
||||
"_mcount:\n\t" \
|
||||
@ -67,9 +69,8 @@ static void __attribute_used__ __mcount (u_long frompc, u_long selfpc)
|
||||
"addu $29,$29,56;\n\t" \
|
||||
"j $31;\n\t" \
|
||||
"move $31,$1;\n\t" \
|
||||
".set reorder;\n\t" \
|
||||
".set at\n\t" \
|
||||
".end _mcount");
|
||||
".end _mcount;\n\t" \
|
||||
".set pop");
|
||||
|
||||
#else
|
||||
|
||||
@ -94,6 +95,8 @@ static void __attribute_used__ __mcount (u_long frompc, u_long selfpc)
|
||||
#define MCOUNT asm(\
|
||||
".globl _mcount;\n\t" \
|
||||
".align 3;\n\t" \
|
||||
".set push;\n\t" \
|
||||
".set nomips16;\n\t" \
|
||||
".type _mcount,@function;\n\t" \
|
||||
".ent _mcount\n\t" \
|
||||
"_mcount:\n\t" \
|
||||
@ -132,8 +135,7 @@ static void __attribute_used__ __mcount (u_long frompc, u_long selfpc)
|
||||
PTR_ADDU_STRING " $29,$29,96;\n\t" \
|
||||
"j $31;\n\t" \
|
||||
"move $31,$1;\n\t" \
|
||||
".set reorder;\n\t" \
|
||||
".set at\n\t" \
|
||||
".end _mcount");
|
||||
".end _mcount;\n\t" \
|
||||
".set pop");
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.set nomips16
|
||||
|
||||
/* void *memset(void *s, int c, size_t n). */
|
||||
|
||||
|
@ -54,6 +54,8 @@
|
||||
.hidden PREINIT_FUNCTION
|
||||
#endif
|
||||
|
||||
.set nomips16
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.p2align 2
|
||||
.globl _init
|
||||
|
@ -36,6 +36,8 @@
|
||||
/* crtn.S puts function epilogues in the .init and .fini sections
|
||||
corresponding to the prologues in crti.S. */
|
||||
|
||||
.set nomips16
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
lw $31,28($sp)
|
||||
.set noreorder
|
||||
|
5
ports/sysdeps/mips/mips32/fpu/Versions
Normal file
5
ports/sysdeps/mips/mips32/fpu/Versions
Normal file
@ -0,0 +1,5 @@
|
||||
libc {
|
||||
GLIBC_2.18 {
|
||||
__mips_fpu_getcw; __mips_fpu_setcw;
|
||||
}
|
||||
}
|
34
ports/sysdeps/mips/mips32/fpu/fpu_control.c
Normal file
34
ports/sysdeps/mips/mips32/fpu/fpu_control.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* FPU control word handling, MIPS version, needed by MIPS16 callers.
|
||||
Copyright (C) 1996-2013 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 <math/fpu_control.c>
|
||||
|
||||
fpu_control_t
|
||||
__mips_fpu_getcw (void)
|
||||
{
|
||||
fpu_control_t cw;
|
||||
|
||||
_FPU_GETCW (cw);
|
||||
return cw;
|
||||
}
|
||||
|
||||
void
|
||||
__mips_fpu_setcw (fpu_control_t cw)
|
||||
{
|
||||
_FPU_SETCW (cw);
|
||||
}
|
1
ports/sysdeps/mips/mips32/mips16/add_n.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/add_n.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/add_n.c>
|
1
ports/sysdeps/mips/mips32/mips16/addmul_1.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/addmul_1.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/addmul_1.c>
|
5
ports/sysdeps/mips/mips32/mips16/fpu/Makefile
Normal file
5
ports/sysdeps/mips/mips32/mips16/fpu/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# Building hard-float libm as MIPS16 actually produces larger code size,
|
||||
# so avoid doing so.
|
||||
ifeq ($(subdir),math)
|
||||
sysdep-CFLAGS += -mno-mips16
|
||||
endif
|
1
ports/sysdeps/mips/mips32/mips16/lshift.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/lshift.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/lshift.c>
|
1
ports/sysdeps/mips/mips32/mips16/mul_1.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/mul_1.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/mul_1.c>
|
1
ports/sysdeps/mips/mips32/mips16/rshift.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/rshift.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/rshift.c>
|
1
ports/sysdeps/mips/mips32/mips16/sub_n.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/sub_n.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/sub_n.c>
|
1
ports/sysdeps/mips/mips32/mips16/submul_1.c
Normal file
1
ports/sysdeps/mips/mips32/mips16/submul_1.c
Normal file
@ -0,0 +1 @@
|
||||
#include <stdlib/submul_1.c>
|
@ -54,6 +54,8 @@
|
||||
.hidden PREINIT_FUNCTION
|
||||
#endif
|
||||
|
||||
.set nomips16
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.p2align 2
|
||||
.globl _init
|
||||
|
@ -36,6 +36,8 @@
|
||||
/* crtn.S puts function epilogues in the .init and .fini sections
|
||||
corresponding to the prologues in crti.S. */
|
||||
|
||||
.set nomips16
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
ld $31,8($sp)
|
||||
ld $28,0($sp)
|
||||
|
@ -54,6 +54,8 @@
|
||||
.hidden PREINIT_FUNCTION
|
||||
#endif
|
||||
|
||||
.set nomips16
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.p2align 2
|
||||
.globl _init
|
||||
|
@ -36,6 +36,8 @@
|
||||
/* crtn.S puts function epilogues in the .init and .fini sections
|
||||
corresponding to the prologues in crti.S. */
|
||||
|
||||
.set nomips16
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
ld $31,8($sp)
|
||||
ld $28,0($sp)
|
||||
|
@ -37,12 +37,17 @@ typedef union dtv
|
||||
} pointer;
|
||||
} dtv_t;
|
||||
|
||||
#ifdef __mips16
|
||||
/* MIPS16 uses GCC builtin to access the TP. */
|
||||
# define READ_THREAD_POINTER() (__builtin_thread_pointer ())
|
||||
#else
|
||||
/* Note: rd must be $v1 to be ABI-conformant. */
|
||||
# define READ_THREAD_POINTER() \
|
||||
({ void *__result; \
|
||||
asm volatile (".set\tpush\n\t.set\tmips32r2\n\t" \
|
||||
"rdhwr\t%0, $29\n\t.set\tpop" : "=v" (__result)); \
|
||||
__result; })
|
||||
#endif
|
||||
|
||||
#else /* __ASSEMBLER__ */
|
||||
# include <tcb-offsets.h>
|
||||
|
@ -25,5 +25,10 @@ mips64*) base_machine=mips64
|
||||
CPPFLAGS="$CPPFLAGS -mabi=$mips_config_abi"
|
||||
fi
|
||||
;;
|
||||
mips*) base_machine=mips machine=mips/mips32/$machine ;;
|
||||
mips*) base_machine=mips
|
||||
case "$CC $CFLAGS $CPPFLAGS " in
|
||||
*" -mips16 "*) machine=mips/mips32/mips16/$machine ;;
|
||||
*) machine=mips/mips32/$machine ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.set nomips16
|
||||
|
||||
/* The function __sigsetjmp_aux saves all the registers, but it can't
|
||||
reliably access the stack or frame pointers, so we pass them in as
|
||||
extra arguments. */
|
||||
|
@ -23,7 +23,7 @@
|
||||
pointer. We do things this way because it's difficult to reliably
|
||||
access them in C. */
|
||||
|
||||
int
|
||||
int __attribute__ ((nomips16))
|
||||
__sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
|
||||
{
|
||||
#ifdef __mips_hard_float
|
||||
|
@ -74,14 +74,15 @@
|
||||
.text
|
||||
.globl ENTRY_POINT
|
||||
.type ENTRY_POINT,@function
|
||||
#ifndef __mips16
|
||||
ENTRY_POINT:
|
||||
#ifdef __PIC__
|
||||
# ifdef __PIC__
|
||||
SETUP_GPX($0)
|
||||
SETUP_GPX64($25,$0)
|
||||
#else
|
||||
# else
|
||||
PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */
|
||||
move $31, $0
|
||||
#endif
|
||||
# endif
|
||||
|
||||
PTR_LA $4, main /* main */
|
||||
PTR_L $5, 0($29) /* argc */
|
||||
@ -92,22 +93,85 @@ ENTRY_POINT:
|
||||
on o32 and quad words (16 bytes) on n32 and n64. */
|
||||
|
||||
and $29, -2 * SZREG
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
# if _MIPS_SIM == _ABIO32
|
||||
PTR_SUBIU $29, 32
|
||||
#endif
|
||||
# endif
|
||||
PTR_LA $7, __libc_csu_init /* init */
|
||||
PTR_LA $8, __libc_csu_fini
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
# if _MIPS_SIM == _ABIO32
|
||||
PTR_S $8, 16($29) /* fini */
|
||||
PTR_S $2, 20($29) /* rtld_fini */
|
||||
PTR_S $29, 24($29) /* stack_end */
|
||||
#else
|
||||
# else
|
||||
move $9, $2 /* rtld_fini */
|
||||
move $10, $29 /* stack_end */
|
||||
#endif
|
||||
# endif
|
||||
jal __libc_start_main
|
||||
hlt: b hlt /* Crash if somehow it does return. */
|
||||
|
||||
#elif _MIPS_SIM == _ABIO32 /* __mips16 */
|
||||
/* MIPS16 entry point. */
|
||||
.set mips16
|
||||
ENTRY_POINT:
|
||||
# ifdef __PIC__
|
||||
li $3, %hi(_gp_disp)
|
||||
addiu $4, $pc, %lo(_gp_disp)
|
||||
sll $3, 16
|
||||
addu $3, $4
|
||||
move $gp, $3
|
||||
# else
|
||||
li $3, %hi(_gp)
|
||||
sll $3, 16
|
||||
addiu $3, %lo(_gp)
|
||||
move $gp, $3
|
||||
# endif
|
||||
/* Tie end of stack frames. */
|
||||
li $4, 0
|
||||
move $31, $4
|
||||
/* Create new SP value in $7, including alignment. */
|
||||
li $4, 2 * SZREG
|
||||
neg $4, $4
|
||||
move $7, $sp
|
||||
and $7, $4
|
||||
addiu $7, -32
|
||||
/* Load arguments with original SP. */
|
||||
lw $5, 0($sp)
|
||||
addiu $6, $sp, PTRSIZE
|
||||
/* Update SP. */
|
||||
move $sp, $7
|
||||
/* Lay out last arguments, and call __libc_start_main(). */
|
||||
# ifdef __PIC__
|
||||
sw $7, 24($sp) /* stack_end */
|
||||
lw $4, %got(__libc_csu_fini)($3)
|
||||
lw $7, %got(__libc_csu_init)($3) /* init */
|
||||
sw $4, 16($sp) /* fini */
|
||||
lw $4, %got(main)($3) /* main */
|
||||
lw $3, %call16(__libc_start_main)($3)
|
||||
sw $2, 20($sp) /* rtld_fini */
|
||||
move $25, $3
|
||||
jalr $3
|
||||
# else
|
||||
lw $4, 1f
|
||||
sw $7, 24($sp) /* stack_end */
|
||||
lw $7, 2f /* init */
|
||||
sw $4, 16($sp) /* fini */
|
||||
lw $4, 3f /* main */
|
||||
sw $2, 20($sp) /* rtld_fini */
|
||||
jal __libc_start_main
|
||||
# endif
|
||||
hlt: b hlt /* Crash if somehow it does return. */
|
||||
# ifndef __PIC__
|
||||
.align 2
|
||||
1: .word __libc_csu_fini
|
||||
2: .word __libc_csu_init
|
||||
3: .word main
|
||||
# endif
|
||||
|
||||
#else /* __mips16 && _MIPS_SIM != _ABIO32 */
|
||||
# error "MIPS16 support for N32/N64 not implemented"
|
||||
|
||||
#endif /* __mips16 */
|
||||
|
||||
/* Define a symbol for the first piece of initialized data. */
|
||||
.data
|
||||
.globl __data_start
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern int _test_and_set (int *__p, int __v) __THROW;
|
||||
extern int _test_and_set (int *__p, int __v)
|
||||
__THROW __attribute__ ((__nomips16__));
|
||||
|
||||
#ifdef __USE_EXTERN_INLINES
|
||||
|
||||
@ -32,7 +33,7 @@ extern int _test_and_set (int *__p, int __v) __THROW;
|
||||
# define _EXTERN_INLINE __extern_inline
|
||||
# endif
|
||||
|
||||
_EXTERN_INLINE int
|
||||
_EXTERN_INLINE int __attribute__ ((__nomips16__))
|
||||
__NTH (_test_and_set (int *__p, int __v))
|
||||
{
|
||||
int __r, __t;
|
||||
|
@ -12,16 +12,33 @@
|
||||
(abicalls pic0) function. */
|
||||
#ifndef __PIC__
|
||||
# if _MIPS_SIM != _ABI64
|
||||
# define LOAD_GP "move %[tmp], $28\n\tla $28, __gnu_local_gp\n\t"
|
||||
# ifndef __mips16
|
||||
# define LOAD_GP "move %[tmp], $28\n\tla $28, __gnu_local_gp\n\t"
|
||||
# else
|
||||
# define LOAD_GP \
|
||||
"li %[tmp], %%hi(__gnu_local_gp)\n\t" \
|
||||
"sll %[tmp], 16\n\t" \
|
||||
"addiu %[tmp], %%lo(__gnu_local_gp)\n\t"
|
||||
# endif
|
||||
# else
|
||||
# define LOAD_GP "move %[tmp], $28\n\tdla $28, __gnu_local_gp\n\t"
|
||||
# endif
|
||||
# define UNLOAD_GP "\n\tmove $28, %[tmp]"
|
||||
#else
|
||||
# define LOAD_GP
|
||||
/* MIPS16 (re)creates the GP value using PC-relative instructions. */
|
||||
# ifdef __mips16
|
||||
# define LOAD_GP \
|
||||
"li %[tmp], %%hi(_gp_disp)\n\t" \
|
||||
"addiu %0, $pc, %%lo(_gp_disp)\n\t" \
|
||||
"sll %[tmp], 16\n\t" \
|
||||
"addu %[tmp], %0\n\t"
|
||||
# else
|
||||
# define LOAD_GP
|
||||
# endif
|
||||
# define UNLOAD_GP
|
||||
#endif
|
||||
|
||||
#ifndef __mips16
|
||||
# define TLS_GD(x) \
|
||||
({ void *__result, *__tmp; \
|
||||
extern void *__tls_get_addr (void *); \
|
||||
@ -62,3 +79,45 @@
|
||||
ADDU " %0,%0,$3" \
|
||||
: "+r" (__result) : : "$3"); \
|
||||
__result; })
|
||||
|
||||
#else /* __mips16 */
|
||||
/* MIPS16 version. */
|
||||
# define TLS_GD(x) \
|
||||
({ void *__result, *__tmp; \
|
||||
extern void *__tls_get_addr (void *); \
|
||||
asm (LOAD_GP ADDIU " %1, %%tlsgd(" #x ")" \
|
||||
"\n\tmove %0, %1" \
|
||||
: "=d" (__result), [tmp] "=&d" (__tmp)); \
|
||||
(int *) __tls_get_addr (__result); })
|
||||
# define TLS_LD(x) \
|
||||
({ void *__result, *__tmp; \
|
||||
extern void *__tls_get_addr (void *); \
|
||||
asm (LOAD_GP ADDIU " %1, %%tlsldm(" #x ")" \
|
||||
"\n\tmove %0, %1" \
|
||||
: "=d" (__result), [tmp] "=&d" (__tmp)); \
|
||||
__result = __tls_get_addr (__result); \
|
||||
asm ("li $3,%%dtprel_hi(" #x ")\n\t" \
|
||||
"sll $3,16\n\t" \
|
||||
"addiu $3,%%dtprel_lo(" #x ")\n\t" \
|
||||
ADDU " %0,%0,$3" \
|
||||
: "+d" (__result) : : "$3"); \
|
||||
__result; })
|
||||
# define TLS_IE(x) \
|
||||
({ void *__result, *__tmp, *__tp; \
|
||||
__tp = __builtin_thread_pointer (); \
|
||||
asm (LOAD_GP LW " $3,%%gottprel(" #x ")(%1)\n\t" \
|
||||
ADDU " %0,%[tp],$3" \
|
||||
: "=&d" (__result), [tmp] "=&d" (__tmp) \
|
||||
: [tp] "d" (__tp) : "$3"); \
|
||||
__result; })
|
||||
# define TLS_LE(x) \
|
||||
({ void *__result, *__tp; \
|
||||
__tp = __builtin_thread_pointer (); \
|
||||
asm ("li $3,%%tprel_hi(" #x ")\n\t" \
|
||||
"sll $3,16\n\t" \
|
||||
"addiu $3,%%tprel_lo(" #x ")\n\t" \
|
||||
ADDU " %0,%[tp],$3" \
|
||||
: "=d" (__result) : [tp] "d" (__tp) : "$3"); \
|
||||
__result; })
|
||||
|
||||
#endif /* __mips16 */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#ifdef __PIC__
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
cfi_startproc; \
|
||||
99: la t9,__syscall_error; \
|
||||
jr t9; \
|
||||
@ -39,6 +40,7 @@ L(syse1):
|
||||
#else
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.set noreorder; \
|
||||
.set nomips16; \
|
||||
.align 2; \
|
||||
cfi_startproc; \
|
||||
99: j __syscall_error; \
|
||||
|
@ -26,6 +26,7 @@
|
||||
#ifdef __PIC__
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
cfi_startproc; \
|
||||
99:; \
|
||||
.set noat; \
|
||||
@ -46,6 +47,7 @@ L(syse1):
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.set noreorder; \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
cfi_startproc; \
|
||||
99: j __syscall_error; \
|
||||
nop; \
|
||||
|
@ -26,6 +26,7 @@
|
||||
#ifdef __PIC__
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
cfi_startproc; \
|
||||
99:; \
|
||||
.set noat; \
|
||||
@ -46,6 +47,7 @@ L(syse1):
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.set noreorder; \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
cfi_startproc; \
|
||||
99: j __syscall_error; \
|
||||
nop; \
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <bits/errno.h>
|
||||
#include <sys/asm.h>
|
||||
|
||||
.set nomips16
|
||||
|
||||
#ifdef _LIBC_REENTRANT
|
||||
|
||||
LOCALSZ= 3
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define PSEUDO_NOERRNO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
ENTRY(name) \
|
||||
.set nomips16; \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall
|
||||
@ -56,6 +57,7 @@
|
||||
#define PSEUDO_ERRVAL(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
ENTRY(name) \
|
||||
.set nomips16; \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall
|
||||
|
@ -30,19 +30,10 @@ weak_alias (__curbrk, ___brk_addr)
|
||||
int
|
||||
__brk (void *addr)
|
||||
{
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
void *newbrk;
|
||||
|
||||
{
|
||||
register long int res __asm__ ("$2");
|
||||
|
||||
asm ("move\t$4,%2\n\t"
|
||||
"li\t%0,%1\n\t"
|
||||
"syscall" /* Perform the system call. */
|
||||
: "=r" (res)
|
||||
: "I" (SYS_ify (brk)), "r" (addr)
|
||||
: "$4", "$7", __SYSCALL_CLOBBERS);
|
||||
newbrk = (void *) res;
|
||||
}
|
||||
newbrk = (void *) INTERNAL_SYSCALL (brk, err, 1, addr);
|
||||
__curbrk = newbrk;
|
||||
|
||||
if (newbrk < addr)
|
||||
|
@ -34,6 +34,7 @@
|
||||
void *parent_tidptr, void *tls, void *child_tidptr) */
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
# define EXTRA_LOCALS 1
|
||||
#else
|
||||
|
@ -27,6 +27,7 @@
|
||||
/* int getcontext (ucontext_t *ucp) */
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
LOCALSZ = 0
|
||||
MASK = 0x00000000
|
||||
#ifdef __PIC__
|
||||
|
@ -27,6 +27,7 @@
|
||||
/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
LOCALSZ = 0
|
||||
ARGSZ = 0
|
||||
MASK = 0x00000000
|
||||
|
13
ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
Normal file
13
ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
ifeq ($(subdir),misc)
|
||||
sysdep_routines += mips16-syscall0 mips16-syscall1 mips16-syscall2
|
||||
sysdep_routines += mips16-syscall3 mips16-syscall4 mips16-syscall5
|
||||
sysdep_routines += mips16-syscall6 mips16-syscall7
|
||||
CFLAGS-mips16-syscall0.c += -fexceptions
|
||||
CFLAGS-mips16-syscall1.c += -fexceptions
|
||||
CFLAGS-mips16-syscall2.c += -fexceptions
|
||||
CFLAGS-mips16-syscall3.c += -fexceptions
|
||||
CFLAGS-mips16-syscall4.c += -fexceptions
|
||||
CFLAGS-mips16-syscall5.c += -fexceptions
|
||||
CFLAGS-mips16-syscall6.c += -fexceptions
|
||||
CFLAGS-mips16-syscall7.c += -fexceptions
|
||||
endif
|
@ -0,0 +1,6 @@
|
||||
libc {
|
||||
GLIBC_PRIVATE {
|
||||
__mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3;
|
||||
__mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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/>. */
|
||||
|
||||
#ifndef MIPS16_SYSCALL_H
|
||||
#define MIPS16_SYSCALL_H 1
|
||||
|
||||
#define __nomips16 __attribute__ ((nomips16))
|
||||
|
||||
union __mips16_syscall_return
|
||||
{
|
||||
long long val;
|
||||
struct
|
||||
{
|
||||
long v0;
|
||||
long v1;
|
||||
}
|
||||
reg;
|
||||
};
|
||||
|
||||
long long __nomips16 __mips16_syscall0 (long number);
|
||||
#define __mips16_syscall0(dummy, number) \
|
||||
__mips16_syscall0 ((long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall1 (long a0,
|
||||
long number);
|
||||
#define __mips16_syscall1(a0, number) \
|
||||
__mips16_syscall1 ((long) (a0), \
|
||||
(long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall2 (long a0, long a1,
|
||||
long number);
|
||||
#define __mips16_syscall2(a0, a1, number) \
|
||||
__mips16_syscall2 ((long) (a0), (long) (a1), \
|
||||
(long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall3 (long a0, long a1, long a2,
|
||||
long number);
|
||||
#define __mips16_syscall3(a0, a1, a2, number) \
|
||||
__mips16_syscall3 ((long) (a0), (long) (a1), (long) (a2), \
|
||||
(long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall4 (long a0, long a1, long a2, long a3,
|
||||
long number);
|
||||
#define __mips16_syscall4(a0, a1, a2, a3, number) \
|
||||
__mips16_syscall4 ((long) (a0), (long) (a1), (long) (a2), \
|
||||
(long) (a3), \
|
||||
(long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall5 (long a0, long a1, long a2, long a3,
|
||||
long a4,
|
||||
long number);
|
||||
#define __mips16_syscall5(a0, a1, a2, a3, a4, number) \
|
||||
__mips16_syscall5 ((long) (a0), (long) (a1), (long) (a2), \
|
||||
(long) (a3), (long) (a4), \
|
||||
(long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall6 (long a0, long a1, long a2, long a3,
|
||||
long a4, long a5,
|
||||
long number);
|
||||
#define __mips16_syscall6(a0, a1, a2, a3, a4, a5, number) \
|
||||
__mips16_syscall6 ((long) (a0), (long) (a1), (long) (a2), \
|
||||
(long) (a3), (long) (a4), (long) (a5), \
|
||||
(long) (number))
|
||||
|
||||
long long __nomips16 __mips16_syscall7 (long a0, long a1, long a2, long a3,
|
||||
long a4, long a5, long a6,
|
||||
long number);
|
||||
#define __mips16_syscall7(a0, a1, a2, a3, a4, a5, a6, number) \
|
||||
__mips16_syscall7 ((long) (a0), (long) (a1), (long) (a2), \
|
||||
(long) (a3), (long) (a4), (long) (a5), \
|
||||
(long) (a6), \
|
||||
(long) (number))
|
||||
|
||||
#endif
|
@ -0,0 +1,30 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall0
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall0 (long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall1
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall1 (long a0,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1,
|
||||
a0);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall2
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall2 (long a0, long a1,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2,
|
||||
a0, a1);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall3
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall3 (long a0, long a1, long a2,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3,
|
||||
a0, a1, a2);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall4
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall4 (long a0, long a1, long a2, long a3,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4,
|
||||
a0, a1, a2, a3);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall5
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall5 (long a0, long a1, long a2, long a3,
|
||||
long a4,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 5,
|
||||
a0, a1, a2, a3, a4);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall6
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall6 (long a0, long a1, long a2, long a3,
|
||||
long a4, long a5,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 6,
|
||||
a0, a1, a2, a3, a4, a5);
|
||||
return ret.val;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/* MIPS16 syscall wrappers.
|
||||
Copyright (C) 2013 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 <mips16-syscall.h>
|
||||
|
||||
#undef __mips16_syscall7
|
||||
|
||||
long long __nomips16
|
||||
__mips16_syscall7 (long a0, long a1, long a2, long a3,
|
||||
long a4, long a5, long a6,
|
||||
long number)
|
||||
{
|
||||
union __mips16_syscall_return ret;
|
||||
ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 7,
|
||||
a0, a1, a2, a3, a4, a5, a6);
|
||||
return ret.val;
|
||||
}
|
@ -1401,6 +1401,8 @@ GLIBC_2.17
|
||||
GLIBC_2.18
|
||||
GLIBC_2.18 A
|
||||
__cxa_thread_atexit_impl F
|
||||
__mips_fpu_getcw F
|
||||
__mips_fpu_setcw F
|
||||
GLIBC_2.2
|
||||
GLIBC_2.2 A
|
||||
_Exit F
|
||||
|
@ -95,17 +95,46 @@
|
||||
#endif
|
||||
|
||||
#undef INTERNAL_SYSCALL
|
||||
#define INTERNAL_SYSCALL(name, err, nr, args...) \
|
||||
#undef INTERNAL_SYSCALL_NCS
|
||||
|
||||
#ifdef __mips16
|
||||
/* There's no MIPS16 syscall instruction, so we go through out-of-line
|
||||
standard MIPS wrappers. These do use inline snippets below though,
|
||||
through INTERNAL_SYSCALL_MIPS16. Spilling the syscall number to
|
||||
memory gives the best code in that case, avoiding the need to save
|
||||
and restore a static register. */
|
||||
|
||||
# include <mips16-syscall.h>
|
||||
|
||||
# define INTERNAL_SYSCALL(name, err, nr, args...) \
|
||||
INTERNAL_SYSCALL_NCS (SYS_ify (name), err, nr, args)
|
||||
|
||||
# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
|
||||
({ \
|
||||
union __mips16_syscall_return ret; \
|
||||
ret.val = __mips16_syscall##nr (args, number); \
|
||||
err = ret.reg.v1; \
|
||||
ret.reg.v0; \
|
||||
})
|
||||
|
||||
# define INTERNAL_SYSCALL_MIPS16(number, err, nr, args...) \
|
||||
internal_syscall##nr ("lw\t%0, %2\n\t", \
|
||||
"R" (number), \
|
||||
0, err, args)
|
||||
|
||||
#else /* !__mips16 */
|
||||
# define INTERNAL_SYSCALL(name, err, nr, args...) \
|
||||
internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t", \
|
||||
"IK" (SYS_ify (name)), \
|
||||
0, err, args)
|
||||
|
||||
#undef INTERNAL_SYSCALL_NCS
|
||||
#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
|
||||
# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
|
||||
internal_syscall##nr (MOVE32 "\t%0, %2\n\t", \
|
||||
"r" (__s0), \
|
||||
number, err, args)
|
||||
|
||||
#endif /* !__mips16 */
|
||||
|
||||
#define internal_syscall0(v0_init, input, number, err, dummy...) \
|
||||
({ \
|
||||
long _sys_result; \
|
||||
|
@ -39,6 +39,7 @@
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
L(pseudo_start): \
|
||||
cfi_startproc; \
|
||||
99: PSEUDO_ERRJMP \
|
||||
|
@ -27,6 +27,7 @@
|
||||
/* int setcontext (const ucontext_t *ucp) */
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
LOCALSZ = 0
|
||||
ARGSZ = 0
|
||||
MASK = 0x00000000
|
||||
|
@ -27,6 +27,7 @@
|
||||
/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
LOCALSZ = 0
|
||||
ARGSZ = 0
|
||||
MASK = 0x00000000
|
||||
|
@ -34,6 +34,7 @@
|
||||
/* int vfork() */
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
LOCALSZ= 1
|
||||
FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
|
||||
GPOFF= FRAMESZ-(1*SZREG)
|
||||
|
Loading…
Reference in New Issue
Block a user