Add support for building as MIPS16 code.

This commit is contained in:
Maciej W. Rozycki 2013-02-27 23:45:07 +00:00
parent 85bd816a60
commit 43301bd3c2
62 changed files with 1041 additions and 47 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -22,6 +22,8 @@
#include <sysdep.h>
.set nomips16
#ifdef __PIC__
.option pic2
#endif

View File

@ -22,6 +22,8 @@
#include <sysdep.h>
.set nomips16
#ifdef __PIC__
.option pic2
#endif

View File

@ -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

View File

@ -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 */

View File

@ -22,7 +22,7 @@
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
double
double __attribute__ ((nomips16))
__ieee754_sqrt (double x)
{
double z;

View File

@ -22,7 +22,7 @@
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
float
float __attribute__ ((nomips16))
__ieee754_sqrtf (float x)
{
float z;

View File

@ -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;

View File

@ -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

View File

@ -18,6 +18,7 @@
#include <sysdep.h>
.set nomips16
/* void *memset(void *s, int c, size_t n). */

View File

@ -54,6 +54,8 @@
.hidden PREINIT_FUNCTION
#endif
.set nomips16
.section .init,"ax",@progbits
.p2align 2
.globl _init

View File

@ -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

View File

@ -0,0 +1,5 @@
libc {
GLIBC_2.18 {
__mips_fpu_getcw; __mips_fpu_setcw;
}
}

View 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);
}

View File

@ -0,0 +1 @@
#include <stdlib/add_n.c>

View File

@ -0,0 +1 @@
#include <stdlib/addmul_1.c>

View 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

View File

@ -0,0 +1 @@
#include <stdlib/lshift.c>

View File

@ -0,0 +1 @@
#include <stdlib/mul_1.c>

View File

@ -0,0 +1 @@
#include <stdlib/rshift.c>

View File

@ -0,0 +1 @@
#include <stdlib/sub_n.c>

View File

@ -0,0 +1 @@
#include <stdlib/submul_1.c>

View File

@ -54,6 +54,8 @@
.hidden PREINIT_FUNCTION
#endif
.set nomips16
.section .init,"ax",@progbits
.p2align 2
.globl _init

View File

@ -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)

View File

@ -54,6 +54,8 @@
.hidden PREINIT_FUNCTION
#endif
.set nomips16
.section .init,"ax",@progbits
.p2align 2
.globl _init

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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; \

View File

@ -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; \

View File

@ -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; \

View File

@ -21,6 +21,8 @@
#include <bits/errno.h>
#include <sys/asm.h>
.set nomips16
#ifdef _LIBC_REENTRANT
LOCALSZ= 3

View File

@ -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

View File

@ -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)

View File

@ -34,6 +34,7 @@
void *parent_tidptr, void *tls, void *child_tidptr) */
.text
.set nomips16
#if _MIPS_SIM == _ABIO32
# define EXTRA_LOCALS 1
#else

View File

@ -27,6 +27,7 @@
/* int getcontext (ucontext_t *ucp) */
.text
.set nomips16
LOCALSZ = 0
MASK = 0x00000000
#ifdef __PIC__

View File

@ -27,6 +27,7 @@
/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */
.text
.set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000

View 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

View File

@ -0,0 +1,6 @@
libc {
GLIBC_PRIVATE {
__mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3;
__mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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; \

View File

@ -39,6 +39,7 @@
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.align 2; \
.set nomips16; \
L(pseudo_start): \
cfi_startproc; \
99: PSEUDO_ERRJMP \

View File

@ -27,6 +27,7 @@
/* int setcontext (const ucontext_t *ucp) */
.text
.set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000

View File

@ -27,6 +27,7 @@
/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
.text
.set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000

View File

@ -34,6 +34,7 @@
/* int vfork() */
.text
.set nomips16
LOCALSZ= 1
FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
GPOFF= FRAMESZ-(1*SZREG)