From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9334 invoked by alias); 27 Feb 2013 01:38:46 -0000 Received: (qmail 9326 invoked by uid 22791); 27 Feb 2013 01:38:45 -0000 X-SWARE-Spam-Status: No, hits=-3.4 required=5.0 tests=AWL,BAYES_20,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_EQ,TW_FN,TW_GJ,TW_TJ X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 27 Feb 2013 01:38:33 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1UAVya-0001Sb-15 from Maciej_Rozycki@mentor.com ; Tue, 26 Feb 2013 17:38:32 -0800 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Tue, 26 Feb 2013 17:38:31 -0800 Received: from [172.30.64.88] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Wed, 27 Feb 2013 01:38:27 +0000 Date: Wed, 27 Feb 2013 01:38:00 -0000 From: "Maciej W. Rozycki" To: "Joseph S. Myers" CC: , Chung-Lin Tang , Steve Ellcey , Richard Sandiford Subject: [PATCH v3] MIPS: MIPS16 support In-Reply-To: Message-ID: References: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2013-02/txt/msg00070.txt.bz2 On Wed, 20 Feb 2013, Joseph S. Myers wrote: > (Given these inconsistencies, I haven't fully reviewed the rest of the > patch contents.) I apologise about the inconsistencies you found, I missed them somehow even though I thought I had adjusted all the ChangeLog entries as I had been making the respective source changes. I have therefore went over the whole change again and verified all ChangeLog data is accurate. And while doing that I actually discovered some issues with the getcw/setcw symbols themselves, so I have corrected them. I have also decided to put as much consistency as possible among all the .set nomips16 pseudo-ops added. Their exact placement has a marginal significance as any .align pseudo-op following that actually emits padding will use the NOP encoding correct for the newly-selected ISA mode. However the absence of any symbol between .set and .align will cause `objdump' to decode that instruction stream according to the old mode, producing garbled output. On the other hand for assembly sources where .set nomips16 applies throughout I think it's most readable if the pseudo-op is located at the top rather than being buried somewhere within the first function defined. Unfortunately our assembly sources lack formatting consistency, but I tried my best. Given I made changes I pushed this new version, as the original, through a full regression test cycle across the following multilibs (both endiannesses each): * standard MIPS ISA, o32 (-mabi=32), * standard MIPS ISA, n64 (-mabi=64), * standard MIPS ISA, n32 (-mabi=n32), * standard MIPS ISA, o32, soft-float (-mabi=32 -msoft-float), * standard MIPS ISA, n64, soft-float (-mabi=64 -msoft-float), * standard MIPS ISA, n32, soft-float (-mabi=n32 -msoft-float), * microMIPS ISA, o32 (-mmicromips -mabi=32), * microMIPS ISA, o32, soft-float (-mmicromips -mabi=32 -msoft-float), * MIPS16 ISA, o32 (-mips16 -mabi=32), * MIPS16 ISA, o32, soft-float (-mips16 -mabi=32 -msoft-float). OK to apply? 2013-02-27 Chung-Lin Tang Maciej W. Rozycki Maxim Kuvyrkov * 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. Maciej glibc-mips16.diff Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/__longjmp.c =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/__longjmp.c 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/__longjmp.c 2013-02-26 22:32:04.447786638 +0000 @@ -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); Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/abort-instr.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/abort-instr.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/abort-instr.h 2013-02-26 22:32:04.447786638 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/bits/atomic.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/bits/atomic.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/bits/atomic.h 2013-02-26 22:32:04.447786638 +0000 @@ -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 */ Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/bsd-_setjmp.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/bsd-_setjmp.S 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/bsd-_setjmp.S 2013-02-26 22:32:04.457754330 +0000 @@ -22,6 +22,8 @@ #include + .set nomips16 + #ifdef __PIC__ .option pic2 #endif Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/bsd-setjmp.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/bsd-setjmp.S 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/bsd-setjmp.S 2013-02-26 22:32:04.457754330 +0000 @@ -22,6 +22,8 @@ #include + .set nomips16 + #ifdef __PIC__ .option pic2 #endif Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/dl-machine.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-machine.h 2013-02-26 22:32:04.457754330 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-trampoline.c =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/dl-trampoline.c 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/dl-trampoline.c 2013-02-26 22:32:04.457754330 +0000 @@ -292,9 +292,11 @@ __dl_runtime_resolve (ElfW(Word) sym_ind #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 */ Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/e_sqrt.c =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu/e_sqrt.c 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/e_sqrt.c 2013-02-26 22:32:04.457754330 +0000 @@ -22,7 +22,7 @@ #if (_MIPS_ISA >= _MIPS_ISA_MIPS2) -double +double __attribute__ ((nomips16)) __ieee754_sqrt (double x) { double z; Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/e_sqrtf.c =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu/e_sqrtf.c 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu/e_sqrtf.c 2013-02-26 22:32:04.457754330 +0000 @@ -22,7 +22,7 @@ #if (_MIPS_ISA >= _MIPS_ISA_MIPS2) -float +float __attribute__ ((nomips16)) __ieee754_sqrtf (float x) { float z; Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/fpu_control.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/fpu_control.h 2013-02-26 22:32:04.457754330 +0000 @@ -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; Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/machine-gmon.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/machine-gmon.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/machine-gmon.h 2013-02-26 22:32:04.457754330 +0000 @@ -37,6 +37,8 @@ static void __attribute_used__ __mcount #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 "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 #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 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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/memset.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/memset.S 2013-02-26 21:08:22.197807296 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/memset.S 2013-02-26 22:32:04.457754330 +0000 @@ -18,6 +18,7 @@ #include + .set nomips16 /* void *memset(void *s, int c, size_t n). */ Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/crti.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips32/crti.S 2013-02-26 21:08:22.206574592 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/crti.S 2013-02-26 22:32:04.457754330 +0000 @@ -54,6 +54,8 @@ .hidden PREINIT_FUNCTION #endif + .set nomips16 + .section .init,"ax",@progbits .p2align 2 .globl _init Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/crtn.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips32/crtn.S 2013-02-26 21:08:22.206574592 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/crtn.S 2013-02-26 22:32:04.457754330 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/fpu/Versions =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/fpu/Versions 2013-02-26 22:32:04.457754330 +0000 @@ -0,0 +1,5 @@ +libc { + GLIBC_2.18 { + __mips_fpu_getcw; __mips_fpu_setcw; + } +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/fpu/fpu_control.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/fpu/fpu_control.c 2013-02-26 22:32:04.457754330 +0000 @@ -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 + . */ + +#include + +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); +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/add_n.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/add_n.c 2013-02-26 22:32:04.457754330 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/addmul_1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/addmul_1.c 2013-02-26 22:32:04.467753501 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/fpu/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/fpu/Makefile 2013-02-26 22:32:04.467753501 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/lshift.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/lshift.c 2013-02-26 22:32:04.467753501 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/mul_1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/mul_1.c 2013-02-26 22:32:04.467753501 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/rshift.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/rshift.c 2013-02-26 22:32:04.467753501 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/sub_n.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/sub_n.c 2013-02-26 22:32:04.467753501 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/submul_1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips32/mips16/submul_1.c 2013-02-26 22:32:04.467753501 +0000 @@ -0,0 +1 @@ +#include Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n32/crti.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/n32/crti.S 2013-02-26 21:08:22.206574592 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n32/crti.S 2013-02-26 22:32:04.467753501 +0000 @@ -54,6 +54,8 @@ .hidden PREINIT_FUNCTION #endif + .set nomips16 + .section .init,"ax",@progbits .p2align 2 .globl _init Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n32/crtn.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/n32/crtn.S 2013-02-26 21:08:22.206574592 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n32/crtn.S 2013-02-26 22:32:04.477753462 +0000 @@ -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) Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n64/crti.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/n64/crti.S 2013-02-26 21:08:22.206574592 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n64/crti.S 2013-02-26 22:32:04.477753462 +0000 @@ -54,6 +54,8 @@ .hidden PREINIT_FUNCTION #endif + .set nomips16 + .section .init,"ax",@progbits .p2align 2 .globl _init Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n64/crtn.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/mips64/n64/crtn.S 2013-02-26 21:08:22.206574592 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/mips64/n64/crtn.S 2013-02-26 22:32:04.477753462 +0000 @@ -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) Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/nptl/tls.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/nptl/tls.h 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/nptl/tls.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/preconfigure =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/preconfigure 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/preconfigure 2013-02-26 22:32:04.477753462 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/setjmp.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/setjmp.S 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/setjmp.S 2013-02-26 22:32:04.477753462 +0000 @@ -17,6 +17,8 @@ #include + .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. */ Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/setjmp_aux.c =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/setjmp_aux.c 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/setjmp_aux.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/start.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/start.S 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/start.S 2013-02-26 22:32:04.477753462 +0000 @@ -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 @@ 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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/sys/tas.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/sys/tas.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/sys/tas.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 # 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; Index: glibc-fsf-trunk-quilt/ports/sysdeps/mips/tls-macros.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/mips/tls-macros.h 2013-02-26 21:08:22.186821407 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/mips/tls-macros.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 */ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/mips32/sysdep.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/mips/mips32/sysdep.h 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/mips32/sysdep.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 @@ #else #define PSEUDO(name, syscall_name, args) \ .set noreorder; \ + .set nomips16; \ .align 2; \ cfi_startproc; \ 99: j __syscall_error; \ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/mips64/n32/sysdep.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/mips/mips64/n32/sysdep.h 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/mips64/n32/sysdep.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 @@ #define PSEUDO(name, syscall_name, args) \ .set noreorder; \ .align 2; \ + .set nomips16; \ cfi_startproc; \ 99: j __syscall_error; \ nop; \ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/mips64/n64/sysdep.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/mips/mips64/n64/sysdep.h 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/mips64/n64/sysdep.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 @@ #define PSEUDO(name, syscall_name, args) \ .set noreorder; \ .align 2; \ + .set nomips16; \ cfi_startproc; \ 99: j __syscall_error; \ nop; \ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/sysdep.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/mips/sysdep.S 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/sysdep.S 2013-02-26 22:32:04.477753462 +0000 @@ -21,6 +21,8 @@ #include #include + .set nomips16 + #ifdef _LIBC_REENTRANT LOCALSZ= 3 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/sysdep.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/mips/sysdep.h 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/mips/sysdep.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/brk.c =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/brk.c 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/brk.c 2013-02-26 22:32:04.477753462 +0000 @@ -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) Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/clone.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/clone.S 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/clone.S 2013-02-26 22:32:04.477753462 +0000 @@ -34,6 +34,7 @@ void *parent_tidptr, void *tls, void *child_tidptr) */ .text + .set nomips16 #if _MIPS_SIM == _ABIO32 # define EXTRA_LOCALS 1 #else Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/getcontext.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/getcontext.S 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/getcontext.S 2013-02-26 22:32:04.477753462 +0000 @@ -27,6 +27,7 @@ /* int getcontext (ucontext_t *ucp) */ .text + .set nomips16 LOCALSZ = 0 MASK = 0x00000000 #ifdef __PIC__ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/makecontext.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/makecontext.S 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/makecontext.S 2013-02-26 22:32:04.477753462 +0000 @@ -27,6 +27,7 @@ /* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */ .text + .set nomips16 LOCALSZ = 0 ARGSZ = 0 MASK = 0x00000000 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2013-02-26 22:32:04.477753462 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2013-02-26 22:32:04.477753462 +0000 @@ -0,0 +1,6 @@ +libc { + GLIBC_PRIVATE { + __mips16_syscall0; __mips16_syscall1; __mips16_syscall2; __mips16_syscall3; + __mips16_syscall4; __mips16_syscall5; __mips16_syscall6; __mips16_syscall7; + } +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c 2013-02-26 22:32:04.477753462 +0000 @@ -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 + . */ + +#include +#include + +#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; +} Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist 2013-02-26 22:32:04.477753462 +0000 @@ -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 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2013-02-26 22:32:04.477753462 +0000 @@ -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 + +# 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; \ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h 2013-02-26 21:08:22.397776709 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h 2013-02-26 22:32:04.477753462 +0000 @@ -39,6 +39,7 @@ # undef PSEUDO # define PSEUDO(name, syscall_name, args) \ .align 2; \ + .set nomips16; \ L(pseudo_start): \ cfi_startproc; \ 99: PSEUDO_ERRJMP \ Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/setcontext.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/setcontext.S 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/setcontext.S 2013-02-26 22:32:04.477753462 +0000 @@ -27,6 +27,7 @@ /* int setcontext (const ucontext_t *ucp) */ .text + .set nomips16 LOCALSZ = 0 ARGSZ = 0 MASK = 0x00000000 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/swapcontext.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/swapcontext.S 2013-02-26 21:08:22.176752232 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/swapcontext.S 2013-02-26 22:32:04.487753065 +0000 @@ -27,6 +27,7 @@ /* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ .text + .set nomips16 LOCALSZ = 0 ARGSZ = 0 MASK = 0x00000000 Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/vfork.S =================================================================== --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/vfork.S 2013-02-26 21:08:22.166795198 +0000 +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/vfork.S 2013-02-26 22:32:04.497752188 +0000 @@ -34,6 +34,7 @@ /* int vfork() */ .text + .set nomips16 LOCALSZ= 1 FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK GPOFF= FRAMESZ-(1*SZREG)