* [PATCH 0/2] MIPS16: MIPS16 support
@ 2013-01-23 4:41 Maciej W. Rozycki
2013-01-23 4:41 ` [PATCH 1/2] MIPS16: Allocate GLIBC_2.18 Maciej W. Rozycki
2013-01-23 4:42 ` [PATCH 2/2] MIPS16: MIPS16 support proper Maciej W. Rozycki
0 siblings, 2 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-23 4:41 UTC (permalink / raw)
To: libc-alpha, libc-ports; +Cc: Chung-Lin Tang
Hi,
This patch mini-series adds MIPS16 support to glibc. It's been split
into two parts per patch submission guidelines. The first part applies to
glibc proper and the second one to the ports add-on. Full descriptions
are included with the patches themselves.
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 1/2] MIPS16: Allocate GLIBC_2.18
2013-01-23 4:41 [PATCH 0/2] MIPS16: MIPS16 support Maciej W. Rozycki
@ 2013-01-23 4:41 ` Maciej W. Rozycki
2013-01-23 4:42 ` [PATCH 2/2] MIPS16: MIPS16 support proper Maciej W. Rozycki
1 sibling, 0 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-23 4:41 UTC (permalink / raw)
To: libc-alpha, libc-ports; +Cc: Chung-Lin Tang
Hi,
This change adds GLIBC_2.18 to the list of defined versions. It is
needed for newly-defined functions required for MIPS16 support.
Please apply.
2013-01-23 Maciej W. Rozycki <macro@codesourcery.com>
* Versions.def (libc): Add GLIBC_2.18.
Maciej
Index: glibc-fsf-trunk-quilt/Versions.def
===================================================================
--- glibc-fsf-trunk-quilt.orig/Versions.def 2012-11-21 23:51:43.000000000 +0000
+++ glibc-fsf-trunk-quilt/Versions.def 2013-01-20 22:12:01.457025518 +0000
@@ -34,6 +34,7 @@ libc {
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
+ GLIBC_2.18
HURD_CTHREADS_0.3
%ifdef EXPORT_UNWIND_FIND_FDE
GCC_3.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-23 4:41 [PATCH 0/2] MIPS16: MIPS16 support Maciej W. Rozycki
2013-01-23 4:41 ` [PATCH 1/2] MIPS16: Allocate GLIBC_2.18 Maciej W. Rozycki
@ 2013-01-23 4:42 ` Maciej W. Rozycki
2013-01-23 17:22 ` Joseph S. Myers
2013-01-24 18:08 ` [PATCH 2/2] MIPS16: MIPS16 support proper Ellcey, Steve
1 sibling, 2 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-23 4:42 UTC (permalink / raw)
To: libc-alpha, libc-ports; +Cc: Chung-Lin Tang
Hi,
This change adds support for building the MIPS port of glibc as MIPS16
code, for the o32 ABI. The MIPS16 instruction set has several limitations
that required adjustments in the library. The benefit is a smaller
footprint of pieces that can actually be compiled to MIPS16 code.
The execution mode can be freely switched between the standard MIPS and
the MIPS16 mode by flipping the ISA bit, that is exposed to the programmer
as bit #0 of the PC and supported by the relevant jump instructions.
Standard MIPS and MIPS16 code can be mixed in a single program both at the
static-link and at the dynamic-load time.
Please note that owing to that property MIPS16 dynamic executables are
supported by glibc already, barring the issue of _FPU_GETCW and _FPU_SETCW
described below, simply by linking and loading such programs with
standard-MIPS glibc binaries; it's just building the library itself that
is not.
Here is how individual issues have been addressed by the change proposed:
1. There are no floating-point MIPS16 instructions nor ones to access
floating-point registers. That required all the affected functions to
be marked with the nomips16 attribute. This applies to functions like
setjmp/longjmp, setcontext/getcontext/etc. that requires access tothe
floating-point register stack.
Further, all the math functions are compiled with the -mno-mips16
compiler option, so that they do not have to be individually marked.
The overhead to factor out individual low-level floating-point
operations, such as addition or multiplication, as standard MIPS code
and call the respective functions as appropriate would be prohibitive
and no code size gain would result.
Finally, the _FPU_GETCW and _FPU_SETCW user-accessible macros have been
rewritten to refer to new helpers so that they can be called in the
MIPS16 mode.
This code is surrounded by an __mips16 macro check that is only going
to work for code built with -mips16 as the preprocessor does not know
the actual mode selected by the compiler. A different solution, such
as a __builtin_mips16 compiler function, would be required for the
macros to work even for functions marked with the mips16 attribute or
compiled to MIPS16 code due to the -mflip-mips16 compiler option. The
solution chosen is I believe the best that we can get and works for the
common case.
I have decided to export prototypes for the new helpers, but I have no
strong preference to do that -- we may well keep them as an internal
implementation detail instead, i.e.:
#define _FPU_GETCW(cw) \
do \
{ \
extern fpu_control_t __fpu_getcw (void) __THROW; \
(cw) = __fpu_getcw (); \
} \
while (0)
-- and likewise for _FPU_SETCW. Suggestions?
2. The MIPS16 BREAK instruction has a limited range of its immediate code
compared to its standard MIPS counterpart. Therefore 63, the maximum
value supported, has been chosen for ABORT_INSTRUCTION.
3. There are no MIPS16 atomic LL or SC instructions. GCC has, since 4.1,
supported suitable built-ins and this change relies on them. In
practice the built-ins produce small snippets of out-of-line standard
MIPS code called from where requested.
4. Several handcoded assembly sequences have been rewritten as
corresponding MIPS16 code. Where there would be no gain from switching
to the MIPS16 mode the existing pieces have been marked with the ".set
nomips16" GAS directive so that they are built as standard MIPS code.
5. New MIPS16 constructor and destructor prologue and epilogue assembly
code has been added. This code is lumped together with all the
individual constructor and destructor call fragments. This works as
long as all the code involved has been built for the same ISA, either
the standard MIPS or the MIPS16 one. This will break if individual
pieces have been built for different ISAs.
To address this properly the MIPS port would have to switch to using
constructor and destructor arrays rather than lumped code (i.e.
DT_INIT_ARRAY and DT_FINI_ARRAY rather than DT_INIT and DT_FINI,
respectively). In this case the ISA bit of the individual array
entries would select the execution mode as appropriate for each call.
To the best of my knowledge the GNU toolchain has supported these
arrays since forever, so this is probably the right moment to switch.
NB mixed standard MIPS/microMIPS binaries suffer from the same problem.
For the time being the change proposed here is the best we can do to
support the common case I believe.
6. There is no MIPS16 RDHWR instruction. To implement the
READ_THREAD_POINTER macro we use the __builtin_thread_pointer GCC
builtin instead. In practice if called from MIPS16 code, this expands
to a call to __mips16_rdhwr that is a small piece of standard MIPS code
that executes RDHWR with the right arguments.
7. There is no MIPS16 SYSCALL instruction. Internal inline syscall
wrappers have been rewritten to small snippets of out-of-line standard
MIPS code where called from MIPS16 code. The snippets have been
designed such as to avoid unnecessary argument shuffling -- hence the
syscall number is passed last.
Consequently __brk is rewritten in terms of INTERNAL_SYSCALL too.
The change was regression-tested successfully for the following
configurations (compiler flag/multilib options), for both endiannesses
each (the -EB and -EL compiler option, respectively):
* 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),
with the MIPS32r2 or MIPS64r2 ISA level selected as applicable. Likewise
new functionality has been tested for:
* MIPS16 ISA, o32 (-mips16 -mabi=32),
* MIPS16 ISA, o32, soft-float (-mips16 -mabi=32 -msoft-float),
producing no failures other to ones already present for the standard MIPS
and microMIPS ISAs.
Questions and comments are welcome; otherwise please apply.
2013-01-23 Chung-Lin Tang <cltang@codesourcery.com>
Maciej W. Rozycki <macro@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com>
ports/
* sysdeps/mips/abort-instr.h (ABORT_INSTRUCTION) [__mips16]:
New macro.
* sysdeps/mips/dl-machine.h (elf_machine_load_address): Add
MIPS16 version.
(RTLD_START): Likewise.
* sysdeps/mips/fpu_control.h (__fpu_getcw) [__mips16]: New
prototype.
(__fpu_setcw) [__mips16]: 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.
* sysdeps/mips/bits/atomic.h
(atomic_compare_and_exchange_val_acq) [__mips16]: Likewise.
(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.
(TLS_GD, TLS_LD, TLS_IE, TLS_LE) [__mips16]: Likewise.
* sysdeps/mips/sys/tas.h (_test_and_set): Add ".set nomips16".
* sysdeps/unix/mips/sysdep.h (PSEUDO_NOERRNO): Likewise.
(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/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): Add MIPS16 version.
* sysdeps/unix/mips/sysdep.S: Add ".set nomips16".
* 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 nomips16.
(__longjmp): New alias.
* sysdeps/mips/dl-trampoline.c (_dl_runtime_resolve): Add MIPS16
version.
(_dl_runtime_pltresolve): Likewise.
* sysdeps/mips/setjmp_aux.c (__sigsetjmp_aux): Add nomips16
attribute.
* sysdeps/mips/fpu/e_sqrt.c (__ieee754_sqrt): Add nomips16
attribute.
* sysdeps/mips/fpu/e_sqrtf.c (__ieee754_sqrtf): Likewise.
* sysdeps/unix/sysv/linux/mips/brk.c (__brk): Replace inline asm
with INTERNAL_SYSCALL.
* sysdeps/mips/mips32/fpu/Implies: New file.
* sysdeps/mips/mips32/fpu/fpu_control.c: New file.
* sysdeps/mips/mips32/mips16/crti.S: New file.
* sysdeps/mips/mips32/mips16/crtn.S: 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/mips/mips32/mips16/Makefile: New file.
* sysdeps/mips/mips32/mips16/fpu/Makefile: New file.
* sysdeps/mips/mips32/mips16/fpu/Versions: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h:
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/unix/sysv/linux/mips/mips32/mips16/Makefile: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions: New file.
* sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist
(GLIBC_2.18): New. Add __fpu_getcw and __fpu_setcw.
* sysdeps/mips/preconfigure: Handle o32 MIPS16 compilation.
Maciej
glibc-mips16.diff
Index: ports/sysdeps/mips/__longjmp.c
===================================================================
--- ports/sysdeps/mips/__longjmp.c 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/__longjmp.c 2013-01-20 19:40:57.097753716 +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: ports/sysdeps/mips/abort-instr.h
===================================================================
--- ports/sysdeps/mips/abort-instr.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/abort-instr.h 2013-01-20 19:40:57.097753716 +0000
@@ -1,2 +1,6 @@
/* An instruction which should crash any program is a breakpoint. */
+#ifdef __mips16
+#define ABORT_INSTRUCTION asm ("break 63")
+#else
#define ABORT_INSTRUCTION asm ("break 255")
+#endif
Index: ports/sysdeps/mips/bits/atomic.h
===================================================================
--- ports/sysdeps/mips/bits/atomic.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/bits/atomic.h 2013-01-20 19:40:57.117793511 +0000
@@ -37,6 +37,40 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;
+/* MIPS16 uses GCC __sync_* builtins to implement the required atomic
+ operations, to abstract out the unsupported assembly instructions.
+ ??? Maybe eventually use them for 32-bit MIPS too? */
+#ifdef __mips16
+# if __GNUC_PREREQ (4, 1)
+
+# 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))
+
+# define atomic_full_barrier() __sync_synchronize ()
+
+# else
+# error "MIPS16 requires GCC with __sync_* builtins"
+# endif
+#else /* !__mips16 */
+
#if _MIPS_SIM == _ABIO32
#define MIPS_PUSH_MIPS2 ".set mips2\n\t"
#else
@@ -454,4 +488,5 @@ typedef uintmax_t uatomic_max_t;
MIPS_SYNC_STR "\n\t" \
".set pop" : : : "memory")
+#endif /* !__mips16 */
#endif /* bits/atomic.h */
Index: ports/sysdeps/mips/bsd-_setjmp.S
===================================================================
--- ports/sysdeps/mips/bsd-_setjmp.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/bsd-_setjmp.S 2013-01-20 19:40:57.137753861 +0000
@@ -26,6 +26,7 @@
.option pic2
#endif
ENTRY (_setjmp)
+ .set nomips16
#ifdef __PIC__
.set noreorder
.cpload t9
Index: ports/sysdeps/mips/bsd-setjmp.S
===================================================================
--- ports/sysdeps/mips/bsd-setjmp.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/bsd-setjmp.S 2013-01-20 19:40:57.156841347 +0000
@@ -26,6 +26,7 @@
.option pic2
#endif
ENTRY (setjmp)
+ .set nomips16
.set noreorder
#ifdef __PIC__
.cpload t9
Index: ports/sysdeps/mips/dl-machine.h
===================================================================
--- ports/sysdeps/mips/dl-machine.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/dl-machine.h 2013-01-20 19:40:57.176855918 +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,6 +224,7 @@ do { \
2) That under Unix the entry is named __start
and not just plain _start. */
+#ifndef __mips16
#define RTLD_START asm (\
".text\n\
" _RTLD_PROLOGUE(ENTRY_POINT) "\
@@ -283,6 +298,91 @@ do { \
".previous"\
);
+#else
+
+/* 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
+
/* Names of the architecture-specific auditing callback functions. */
# if _MIPS_SIM == _ABIO32
# define ARCH_LA_PLTENTER mips_o32_gnu_pltenter
Index: ports/sysdeps/mips/dl-trampoline.c
===================================================================
--- ports/sysdeps/mips/dl-trampoline.c 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/dl-trampoline.c 2013-01-20 19:40:57.196878136 +0000
@@ -292,8 +292,11 @@ __dl_runtime_resolve (ElfW(Word) sym_ind
#endif
+#ifndef __mips16
+
asm ("\n\
.text\n\
+ .set nomips16\n\
.align 2\n\
.globl _dl_runtime_resolve\n\
.type _dl_runtime_resolve,@function\n\
@@ -350,6 +353,7 @@ _dl_runtime_resolve:\n\
asm ("\n\
.text\n\
+ .set nomips16\n\
.align 2\n\
.globl _dl_runtime_pltresolve\n\
.type _dl_runtime_pltresolve,@function\n\
@@ -381,3 +385,131 @@ _dl_runtime_pltresolve:\n\
.previous\n\
");
+#elif _MIPS_SIM == _ABIO32
+
+/* MIPS16 version, O32 only. */
+
+asm ("\n\
+ .text\n\
+ .set mips16\n\
+ .align 2\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\
+ .set mips16\n\
+ .align 2\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
+#error "MIPS16 support for N32/N64 not implemented"
+#endif /* __mips16 */
Index: ports/sysdeps/mips/fpu/e_sqrt.c
===================================================================
--- ports/sysdeps/mips/fpu/e_sqrt.c 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/fpu/e_sqrt.c 2013-01-20 19:40:57.216896761 +0000
@@ -22,7 +22,7 @@
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
-double
+double __attribute__ ((nomips16))
__ieee754_sqrt (double x)
{
double z;
Index: ports/sysdeps/mips/fpu/e_sqrtf.c
===================================================================
--- ports/sysdeps/mips/fpu/e_sqrtf.c 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/fpu/e_sqrtf.c 2013-01-20 19:40:57.236875700 +0000
@@ -22,7 +22,7 @@
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
-float
+float __attribute__ ((nomips16))
__ieee754_sqrtf (float x)
{
float z;
Index: ports/sysdeps/mips/fpu_control.h
===================================================================
--- ports/sysdeps/mips/fpu_control.h 2013-01-16 00:04:04.000000000 +0000
+++ ports/sysdeps/mips/fpu_control.h 2013-01-23 01:25:04.047168836 +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. */
+extern fpu_control_t __fpu_getcw (void) __THROW;
+extern void __fpu_setcw (fpu_control_t) __THROW;
+#ifdef __mips16
+#define _FPU_GETCW(cw) do { (cw) = __fpu_getcw (); } while (0)
+#define _FPU_SETCW(cw) __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: ports/sysdeps/mips/machine-gmon.h
===================================================================
--- ports/sysdeps/mips/machine-gmon.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/machine-gmon.h 2013-01-20 19:40:57.256890706 +0000
@@ -35,6 +35,8 @@ static void __attribute_used__ __mcount
#endif
#define MCOUNT asm(\
+ ".set push;\n\t" \
+ ".set nomips16;\n\t" \
".globl _mcount;\n\t" \
".align 2;\n\t" \
".type _mcount,@function;\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
@@ -92,6 +93,8 @@ static void __attribute_used__ __mcount
#endif
#define MCOUNT asm(\
+ ".set push;\n\t" \
+ ".set nomips16;\n\t" \
".globl _mcount;\n\t" \
".align 3;\n\t" \
".type _mcount,@function;\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: ports/sysdeps/mips/memset.S
===================================================================
--- ports/sysdeps/mips/memset.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/memset.S 2013-01-20 19:40:57.276543548 +0000
@@ -28,6 +28,7 @@
#endif
ENTRY (memset)
+ .set nomips16
.set noreorder
slti t1, a2, 8 # Less than 8?
Index: ports/sysdeps/mips/mips32/fpu/fpu_control.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/fpu/fpu_control.c 2013-01-20 23:16:11.026712794 +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
+ <http://www.gnu.org/licenses/>. */
+
+#include <math/fpu_control.c>
+
+fpu_control_t
+__fpu_getcw (void)
+{
+ fpu_control_t cw;
+
+ _FPU_GETCW(cw);
+ return cw;
+}
+
+void
+__fpu_setcw (fpu_control_t cw)
+{
+ _FPU_SETCW(cw);
+}
Index: ports/sysdeps/mips/mips32/mips16/add_n.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/add_n.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/add_n.c>
Index: ports/sysdeps/mips/mips32/mips16/addmul_1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/addmul_1.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/addmul_1.c>
Index: ports/sysdeps/mips/mips32/mips16/crti.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/crti.S 2013-01-20 20:05:43.816556531 +0000
@@ -0,0 +1,111 @@
+/* Special .init and .fini section support for MIPS16 (o32).
+ 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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/>. */
+
+/* crti.S puts a function prologue at the beginning of the .init and
+ .fini sections and defines global symbols for those addresses, so
+ they can be called as functions. The symbols _init and _fini are
+ magic and cause the linker to emit DT_INIT and DT_FINI. */
+
+#include <libc-symbols.h>
+
+#ifndef PREINIT_FUNCTION
+# define PREINIT_FUNCTION __gmon_start__
+#endif
+
+#ifndef PREINIT_FUNCTION_WEAK
+# define PREINIT_FUNCTION_WEAK 1
+#endif
+
+#if PREINIT_FUNCTION_WEAK
+ weak_extern (PREINIT_FUNCTION)
+#else
+ .hidden PREINIT_FUNCTION
+#endif
+
+ .section .init, "ax", @progbits
+ .p2align 2
+ .globl _init
+ .type _init, @function
+_init:
+ li $2, %hi(_gp_disp)
+ addiu $3, $pc, %lo(_gp_disp)
+ sll $2, 16
+ addu $2, $3
+#if _MIPS_ISA >= _MIPS_ISA_MIPS32
+ save 32, $31
+#else
+ addiu $sp, -32
+ sw $31, 28($sp)
+#endif
+ move $28, $2
+ sw $2, 16($sp)
+#if PREINIT_FUNCTION_WEAK
+ lw $3, %got(PREINIT_FUNCTION)($2)
+ beqz $3, .Lno_weak_fn
+ lw $2, %call16(PREINIT_FUNCTION)($2)
+ .set noreorder
+ .set nomacro
+ jalr $2
+ move $25, $2
+ .set macro
+ .set reorder
+.Lno_weak_fn:
+#else
+ lw $2, %got(PREINIT_FUNCTION)($2)
+ .set noreorder
+ .set nomacro
+ jalr $2
+ move $25, $2
+ .set macro
+ .set reorder
+#endif
+
+ .section .fini, "ax", @progbits
+ .p2align 2
+ .globl _fini
+ .type _fini, @function
+_fini:
+ li $2, %hi(_gp_disp)
+ addiu $3, $pc, %lo(_gp_disp)
+ sll $2, 16
+ addu $2, $3
+#if _MIPS_ISA >= _MIPS_ISA_MIPS32
+ save 32, $31
+#else
+ addiu $sp, -32
+ sw $31, 28($sp)
+#endif
+ move $28, $2
+ sw $2, 16($sp)
Index: ports/sysdeps/mips/mips32/mips16/crtn.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/crtn.S 2013-01-20 20:00:38.716871098 +0000
@@ -0,0 +1,57 @@
+/* Special .init and .fini section support for MIPS16 (o32).
+ 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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/>. */
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+ corresponding to the prologues in crti.S. */
+
+ .section .init, "ax", @progbits
+#if _MIPS_ISA >= _MIPS_ISA_MIPS32
+ restore 32, $31
+ j $31
+#else
+ lw $7, 28($sp)
+ addiu $sp, 32
+ j $7
+#endif
+
+ .section .fini, "ax", @progbits
+#if _MIPS_ISA >= _MIPS_ISA_MIPS32
+ restore 32, $31
+ j $31
+#else
+ lw $7, 28($sp)
+ addiu $sp, 32
+ j $7
+#endif
Index: ports/sysdeps/mips/mips32/mips16/fpu/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/fpu/Makefile 2013-01-20 19:40:57.296892628 +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: ports/sysdeps/mips/mips32/mips16/fpu/Versions
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/fpu/Versions 2013-01-20 22:11:01.057025227 +0000
@@ -0,0 +1,5 @@
+libc {
+ GLIBC_2.18 {
+ __fpu_getcw; __fpu_getcw;
+ }
+}
Index: ports/sysdeps/mips/mips32/mips16/lshift.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/lshift.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/lshift.c>
Index: ports/sysdeps/mips/mips32/mips16/mul_1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/mul_1.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/mul_1.c>
Index: ports/sysdeps/mips/mips32/mips16/rshift.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/rshift.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/rshift.c>
Index: ports/sysdeps/mips/mips32/mips16/sub_n.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/sub_n.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/sub_n.c>
Index: ports/sysdeps/mips/mips32/mips16/submul_1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/submul_1.c 2013-01-20 19:40:57.296892628 +0000
@@ -0,0 +1 @@
+#include <stdlib/submul_1.c>
Index: ports/sysdeps/mips/nptl/tls.h
===================================================================
--- ports/sysdeps/mips/nptl/tls.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/nptl/tls.h 2013-01-20 19:40:57.296892628 +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 <tcb-offsets.h>
Index: ports/sysdeps/mips/preconfigure
===================================================================
--- ports/sysdeps/mips/preconfigure 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/preconfigure 2013-01-20 19:40:57.306553118 +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: ports/sysdeps/mips/setjmp.S
===================================================================
--- ports/sysdeps/mips/setjmp.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/setjmp.S 2013-01-20 19:40:57.326814470 +0000
@@ -24,6 +24,7 @@
.option pic2
#endif
ENTRY (__sigsetjmp)
+ .set nomips16
#ifdef __PIC__
.set noreorder
.cpload t9
Index: ports/sysdeps/mips/setjmp_aux.c
===================================================================
--- ports/sysdeps/mips/setjmp_aux.c 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/setjmp_aux.c 2013-01-20 19:40:57.346890569 +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: ports/sysdeps/mips/start.S
===================================================================
--- ports/sysdeps/mips/start.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/start.S 2013-01-20 19:40:57.366883392 +0000
@@ -74,6 +74,7 @@
.text
.globl ENTRY_POINT
.type ENTRY_POINT,@function
+#ifndef __mips16
ENTRY_POINT:
#ifdef __PIC__
SETUP_GPX($0)
@@ -108,6 +109,68 @@
jal __libc_start_main
hlt: b hlt /* Crash if somehow it does return. */
+#elif _MIPS_SIM == _ABIO32
+ /* MIPS16 entry point. */
+ENTRY_POINT:
+ .set mips16
+#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
+#error "MIPS16 support for N32/N64 not implemented"
+#endif
+
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
Index: ports/sysdeps/mips/sys/tas.h
===================================================================
--- ports/sysdeps/mips/sys/tas.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/sys/tas.h 2013-01-20 19:40:57.376549265 +0000
@@ -24,7 +24,7 @@
__BEGIN_DECLS
-extern int _test_and_set (int *__p, int __v) __THROW;
+extern int __attribute__((nomips16)) test_and_set (int *__p, int __v) __THROW;
#ifdef __USE_EXTERN_INLINES
@@ -32,7 +32,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: ports/sysdeps/mips/tls-macros.h
===================================================================
--- ports/sysdeps/mips/tls-macros.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/mips/tls-macros.h 2013-01-20 19:40:57.406635785 +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,46 @@
ADDU " %0,%0,$3" \
: "+r" (__result) : : "$3"); \
__result; })
+
+#else
+
+/* 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
Index: ports/sysdeps/unix/mips/mips32/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/mips32/sysdep.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/mips/mips32/sysdep.h 2013-01-20 19:40:57.406635785 +0000
@@ -23,6 +23,7 @@
backwards into the previous fn. */
#ifdef __PIC__
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.align 2; \
99: la t9,__syscall_error; \
jr t9; \
@@ -36,6 +37,7 @@
L(syse1):
#else
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.set noreorder; \
.align 2; \
99: j __syscall_error; \
Index: ports/sysdeps/unix/mips/mips64/n32/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/mips64/n32/sysdep.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/mips/mips64/n32/sysdep.h 2013-01-20 19:40:57.426877081 +0000
@@ -25,6 +25,7 @@
backwards into the previous fn. */
#ifdef __PIC__
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.align 2; \
99:; \
.set noat; \
@@ -40,6 +41,7 @@
L(syse1):
#else
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.set noreorder; \
.align 2; \
99: j __syscall_error; \
Index: ports/sysdeps/unix/mips/mips64/n64/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/mips64/n64/sysdep.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/mips/mips64/n64/sysdep.h 2013-01-20 19:40:57.446887899 +0000
@@ -25,6 +25,7 @@
backwards into the previous fn. */
#ifdef __PIC__
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.align 2; \
99:; \
.set noat; \
@@ -40,6 +41,7 @@
L(syse1):
#else
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.set noreorder; \
.align 2; \
99: j __syscall_error; \
Index: ports/sysdeps/unix/mips/sysdep.S
===================================================================
--- ports/sysdeps/unix/mips/sysdep.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/mips/sysdep.S 2013-01-20 19:40:57.466877139 +0000
@@ -21,6 +21,9 @@
#include <bits/errno.h>
#include <sys/asm.h>
+ /* Not MIPS16 code. */
+ .set nomips16
+
#ifdef _LIBC_REENTRANT
LOCALSZ= 3
Index: ports/sysdeps/unix/mips/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/sysdep.h 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/mips/sysdep.h 2013-01-20 19:40:57.486831430 +0000
@@ -42,6 +42,7 @@
#define PSEUDO_NOERRNO(name, syscall_name, args) \
.align 2; \
ENTRY(name) \
+ .set nomips16; \
.set noreorder; \
li v0, SYS_ify(syscall_name); \
syscall
@@ -54,6 +55,7 @@
#define PSEUDO_ERRVAL(name, syscall_name, args) \
.align 2; \
ENTRY(name) \
+ .set nomips16; \
.set noreorder; \
li v0, SYS_ify(syscall_name); \
syscall
Index: ports/sysdeps/unix/sysv/linux/mips/brk.c
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/brk.c 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/brk.c 2013-01-20 19:40:57.506879197 +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: ports/sysdeps/unix/sysv/linux/mips/clone.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/clone.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/clone.S 2013-01-20 19:40:57.526854098 +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: ports/sysdeps/unix/sysv/linux/mips/getcontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/getcontext.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/getcontext.S 2013-01-20 19:40:57.546859991 +0000
@@ -27,6 +27,7 @@
/* int getcontext (ucontext_t *ucp) */
.text
+ .set nomips16
LOCALSZ = 0
MASK = 0x00000000
#ifdef __PIC__
Index: ports/sysdeps/unix/sysv/linux/mips/makecontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/makecontext.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/makecontext.S 2013-01-20 19:40:57.546859991 +0000
@@ -27,6 +27,7 @@
/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */
.text
+ .set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2013-01-20 19:40:57.546859991 +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: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2013-01-20 19:40:57.546859991 +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: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2013-01-20 19:40:57.546859991 +0000
@@ -0,0 +1,91 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2013-01-20 19:40:57.546859991 +0000
@@ -0,0 +1,32 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2013-01-20 19:40:57.546859991 +0000
@@ -0,0 +1,34 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2013-01-20 19:40:57.546859991 +0000
@@ -0,0 +1,35 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
+//libc_hidden_def (__mips16_syscall2)
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2013-01-20 19:40:57.546859991 +0000
@@ -0,0 +1,34 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2013-01-20 19:40:57.546859991 +0000
@@ -0,0 +1,34 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c 2013-01-20 19:40:57.556541697 +0000
@@ -0,0 +1,35 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c 2013-01-20 19:40:57.556541697 +0000
@@ -0,0 +1,35 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c 2013-01-20 19:40:57.556541697 +0000
@@ -0,0 +1,35 @@
+/* MIPS16 syscall wrappers.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist 2012-11-21 23:51:44.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist 2013-01-20 23:50:55.947782276 +0000
@@ -2250,3 +2250,7 @@ GLIBC_2.17
clock_nanosleep F
clock_settime F
secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __fpu_getcw F
+ __fpu_setcw F
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2013-01-19 19:25:30.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2013-01-20 19:40:57.556541697 +0000
@@ -84,17 +84,47 @@
#endif
#undef INTERNAL_SYSCALL
+#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...) \
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: ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h 2013-01-17 01:18:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h 2013-01-20 19:40:57.576858974 +0000
@@ -45,6 +45,7 @@
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.align 2; \
+ .set nomips16; \
L(pseudo_start): \
cfi_startproc; \
99: PSEUDO_ERRJMP \
Index: ports/sysdeps/unix/sysv/linux/mips/setcontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/setcontext.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/setcontext.S 2013-01-20 19:40:57.596908144 +0000
@@ -27,6 +27,7 @@
/* int setcontext (const ucontext_t *ucp) */
.text
+ .set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000
Index: ports/sysdeps/unix/sysv/linux/mips/swapcontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/swapcontext.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/swapcontext.S 2013-01-20 19:40:57.616906450 +0000
@@ -27,6 +27,7 @@
/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
.text
+ .set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000
Index: ports/sysdeps/unix/sysv/linux/mips/vfork.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/vfork.S 2013-01-17 00:55:17.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/vfork.S 2013-01-20 19:40:57.646908672 +0000
@@ -34,6 +34,7 @@
/* int vfork() */
.text
+ .set nomips16
LOCALSZ= 1
FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
GPOFF= FRAMESZ-(1*SZREG)
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-23 4:42 ` [PATCH 2/2] MIPS16: MIPS16 support proper Maciej W. Rozycki
@ 2013-01-23 17:22 ` Joseph S. Myers
2013-01-24 10:10 ` Chung-Lin Tang
2013-02-20 16:19 ` [PATCH v2] MIPS: MIPS16 support Maciej W. Rozycki
2013-01-24 18:08 ` [PATCH 2/2] MIPS16: MIPS16 support proper Ellcey, Steve
1 sibling, 2 replies; 26+ messages in thread
From: Joseph S. Myers @ 2013-01-23 17:22 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: libc-ports, Chung-Lin Tang
On Wed, 23 Jan 2013, Maciej W. Rozycki wrote:
> Index: ports/sysdeps/mips/__longjmp.c
> ===================================================================
> --- ports/sysdeps/mips/__longjmp.c 2013-01-17 00:55:17.000000000 +0000
> +++ ports/sysdeps/mips/__longjmp.c 2013-01-20 19:40:57.097753716 +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);
Why is the renaming / alias needed?
> Index: ports/sysdeps/mips/abort-instr.h
> ===================================================================
> --- ports/sysdeps/mips/abort-instr.h 2013-01-17 00:55:17.000000000 +0000
> +++ ports/sysdeps/mips/abort-instr.h 2013-01-20 19:40:57.097753716 +0000
> @@ -1,2 +1,6 @@
> /* An instruction which should crash any program is a breakpoint. */
> +#ifdef __mips16
> +#define ABORT_INSTRUCTION asm ("break 63")
> +#else
> #define ABORT_INSTRUCTION asm ("break 255")
> +#endif
Indentation inside #if, "# define".
> +/* MIPS16 uses GCC __sync_* builtins to implement the required atomic
> + operations, to abstract out the unsupported assembly instructions.
> + ??? Maybe eventually use them for 32-bit MIPS too? */
> +#ifdef __mips16
> +# if __GNUC_PREREQ (4, 1)
glibc requires at least 4.3 to build, so no such condition is needed in an
internal header.
However, __sync_* are obsolete; the __atomic_* built-in functions
(supported in 4.7 and later, well-optimized for MIPS in 4.8 and later) are
preferred because they allow more precise specification of the barrier
semantics in particular cases. So if building with 4.8 or later, you
should use the existing definitions in terms of __atomic_* that are
already used in those circumstances for MIPS - and probably use them for
the (4.7 and MIPS16) combination, since they won't be any worse than
__sync_*. Fallbacks using __sync_* should only be for the (older GCC,
MIPS16) combination. So the logic in the file should be:
#if (4.8 or later, or 4.7 and MIPS16)
existing implementation using __atomic_*
#elif (MIPS16)
implementation using __sync_*, for older GCC and MIPS16
#else
existing implementation using inline asm
#endif
> +#else
> +
> +/* 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 (\
Indentation, "# define". Many further cases in this patch as well, not
individually pointed out.
> /* Macros for accessing the hardware control word. */
> +extern fpu_control_t __fpu_getcw (void) __THROW;
> +extern void __fpu_setcw (fpu_control_t) __THROW;
> +#ifdef __mips16
> +#define _FPU_GETCW(cw) do { (cw) = __fpu_getcw (); } while (0)
> +#define _FPU_SETCW(cw) __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
Names __mips_fpu_getcw and __mips_fpu_setcw might reduce any risk of
conflicts with any future architecture-independent internal function?
> + _FPU_GETCW(cw);
> + _FPU_SETCW(cw);
Missing space before '('.
> Index: ports/sysdeps/mips/mips32/mips16/fpu/Versions
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ ports/sysdeps/mips/mips32/mips16/fpu/Versions 2013-01-20 22:11:01.057025227 +0000
> @@ -0,0 +1,5 @@
> +libc {
> + GLIBC_2.18 {
> + __fpu_getcw; __fpu_getcw;
> + }
> +}
The public ABI exported by glibc should not depend on whether glibc itself
was built as MIPS16; remember that these functions will be needed by
MIPS16 code linked with a MIPS32 glibc. So this Versions file should not
be in a mips16 sysdeps directory.
> Index: ports/sysdeps/mips/sys/tas.h
> ===================================================================
> --- ports/sysdeps/mips/sys/tas.h 2013-01-17 00:55:17.000000000 +0000
> +++ ports/sysdeps/mips/sys/tas.h 2013-01-20 19:40:57.376549265 +0000
> @@ -24,7 +24,7 @@
>
> __BEGIN_DECLS
>
> -extern int _test_and_set (int *__p, int __v) __THROW;
> +extern int __attribute__((nomips16)) test_and_set (int *__p, int __v) __THROW;
>
> #ifdef __USE_EXTERN_INLINES
>
> @@ -32,7 +32,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;
This is an installed header, so you need to use __nomips16__ rather than
just plain nomips16.
> Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2013-01-20 19:40:57.546859991 +0000
> @@ -0,0 +1,91 @@
> +/* MIPS16 syscall wrappers.
> + Copyright (C) 2013 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> + Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
We don't put "Contributed by" lines in new files in glibc.
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, write to the Free
> + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> + 02111-1307 USA. */
All files in glibc should now use a URL instead of an FSF postal address.
These points apply similarly to other new files.
Please send a revised patch for review.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-23 17:22 ` Joseph S. Myers
@ 2013-01-24 10:10 ` Chung-Lin Tang
2013-01-24 13:13 ` Maciej W. Rozycki
2013-02-20 16:19 ` [PATCH v2] MIPS: MIPS16 support Maciej W. Rozycki
1 sibling, 1 reply; 26+ messages in thread
From: Chung-Lin Tang @ 2013-01-24 10:10 UTC (permalink / raw)
To: Joseph S. Myers; +Cc: Maciej W. Rozycki, libc-ports
On 2013/1/24 01:22 AM, Joseph S. Myers wrote:
>>
>> > -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);
> Why is the renaming / alias needed?
>
This was because the declaration of __longjmp() in setjmp.h prohibited
us from tagging it directly with __attribute__ ((nomips16)) locally;
there will be a declaration inconsistent with header error.
Chung-Lin
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-24 10:10 ` Chung-Lin Tang
@ 2013-01-24 13:13 ` Maciej W. Rozycki
2013-01-24 13:56 ` Richard Sandiford
0 siblings, 1 reply; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-24 13:13 UTC (permalink / raw)
To: Richard Sandiford, Chung-Lin Tang; +Cc: Joseph S. Myers, libc-ports
On Thu, 24 Jan 2013, Chung-Lin Tang wrote:
> >> > -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);
> > Why is the renaming / alias needed?
> >
>
> This was because the declaration of __longjmp() in setjmp.h prohibited
> us from tagging it directly with __attribute__ ((nomips16)) locally;
> there will be a declaration inconsistent with header error.
Indeed, GCC goes through a great pain to enforce consistency between a
function's prototype and the corresponding definition as far as the mips16
and nomips16 attributes are concerned. On the other hand it is possible
to provide a prototype with neither attribute and freely choose the
instruction encoding used for the definition with either of the -mips16
and -mno-mips16 command line options applied when building the relevant
source file.
I have no idea where this dichotomy comes from -- Richard, do you happen
to know? I'd be happy to get enlightened.
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-24 13:13 ` Maciej W. Rozycki
@ 2013-01-24 13:56 ` Richard Sandiford
0 siblings, 0 replies; 26+ messages in thread
From: Richard Sandiford @ 2013-01-24 13:56 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Chung-Lin Tang, Joseph S. Myers, libc-ports
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
> On Thu, 24 Jan 2013, Chung-Lin Tang wrote:
>
>> >> > -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);
>> > Why is the renaming / alias needed?
>> >
>>
>> This was because the declaration of __longjmp() in setjmp.h prohibited
>> us from tagging it directly with __attribute__ ((nomips16)) locally;
>> there will be a declaration inconsistent with header error.
>
> Indeed, GCC goes through a great pain to enforce consistency between a
> function's prototype and the corresponding definition as far as the mips16
> and nomips16 attributes are concerned. On the other hand it is possible
> to provide a prototype with neither attribute and freely choose the
> instruction encoding used for the definition with either of the -mips16
> and -mno-mips16 command line options applied when building the relevant
> source file.
>
> I have no idea where this dichotomy comes from -- Richard, do you happen
> to know? I'd be happy to get enlightened.
As it happens, this very topic was raised on the GCC list recently:
http://gcc.gnu.org/ml/gcc/2013-01/msg00133.html
http://gcc.gnu.org/ml/gcc/2013-01/msg00229.html
Richard
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-23 4:42 ` [PATCH 2/2] MIPS16: MIPS16 support proper Maciej W. Rozycki
2013-01-23 17:22 ` Joseph S. Myers
@ 2013-01-24 18:08 ` Ellcey, Steve
2013-01-25 5:14 ` Maciej W. Rozycki
1 sibling, 1 reply; 26+ messages in thread
From: Ellcey, Steve @ 2013-01-24 18:08 UTC (permalink / raw)
To: Maciej W. Rozycki, libc-alpha, libc-ports; +Cc: Chung-Lin Tang
Maciej,
I was able to apply your patches and build a MIPS16 glibc (multiple ones actually for mips32,
mips32r2, big & little endian, soft & hard float), so that was great. I am having trouble running executables
that I link with those libraries though. I am using qemu for my testing and the same qemu that runs
mips32r2 binaries just fine won't run something compiled with -mips32r2 -mips16 and linked with the mips16
glibc that I built.
After some poking around I think the problem is not the glibc that I built but with crti.o and crtn.o. If I use
regular mips32 versions of these crt files and mips16 built versions of everything else (main program, glibc,
libgcc, etc.) then I can run a simple hello world program, if I use the mips16 versions of crti and crtn I get:
mips-mti-linux-gnu-gcc -mips32r2 -mips16 '-Wl,--dynamic-linker=/local/home/sellcey/gcc/mips16/sysroot-mips-mti-linux-gnu/mips16/usr/lib/ld-2.17.90.so' '-Wl,-rpath=/local/home/sellcey/gcc/mips16/sysroot-mips-mti-linux-gnu/mips16/usr/lib:/local/home/sellcey/gcc/mips16/install-mips-mti-linux-gnu/mips-mti-linux-gnu/lib/mips16' hi.c -o x
mips-mti-linux-gnu-qemu -r 2.6.38 ./x
hi
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Note that it did print 'hi' before getting the signal.
If I try adding '-static' then I get:
mips-mti-linux-gnu-gcc -static -mips32r2 -mips16 hi.c -o x
mips-mti-linux-gnu-qemu -r 2.6.38 ./x
qemu: uncaught target signal 4 (Illegal instruction) - core dumped
I was wondering if you have any idea what could be causing this. Should the standard qemu be able
to run mips16 executables with no changes?
Steve Ellcey
sellcey@mips.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-24 18:08 ` [PATCH 2/2] MIPS16: MIPS16 support proper Ellcey, Steve
@ 2013-01-25 5:14 ` Maciej W. Rozycki
2013-01-25 13:59 ` Richard Sandiford
2013-01-25 22:10 ` Steve Ellcey
0 siblings, 2 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-25 5:14 UTC (permalink / raw)
To: Ellcey, Steve; +Cc: libc-alpha, libc-ports, Chung-Lin Tang
Steve,
> After some poking around I think the problem is not the glibc that I built but with crti.o and crtn.o. If I use
> regular mips32 versions of these crt files and mips16 built versions of everything else (main program, glibc,
> libgcc, etc.) then I can run a simple hello world program, if I use the mips16 versions of crti and crtn I get:
>
>
> mips-mti-linux-gnu-gcc -mips32r2 -mips16 '-Wl,--dynamic-linker=/local/home/sellcey/gcc/mips16/sysroot-mips-mti-linux-gnu/mips16/usr/lib/ld-2.17.90.so' '-Wl,-rpath=/local/home/sellcey/gcc/mips16/sysroot-mips-mti-linux-gnu/mips16/usr/lib:/local/home/sellcey/gcc/mips16/install-mips-mti-linux-gnu/mips-mti-linux-gnu/lib/mips16' hi.c -o x
>
> mips-mti-linux-gnu-qemu -r 2.6.38 ./x
> hi
> qemu: uncaught target signal 11 (Segmentation fault) - core dumped
>
> Note that it did print 'hi' before getting the signal.
>
> If I try adding '-static' then I get:
>
> mips-mti-linux-gnu-gcc -static -mips32r2 -mips16 hi.c -o x
> mips-mti-linux-gnu-qemu -r 2.6.38 ./x
> qemu: uncaught target signal 4 (Illegal instruction) - core dumped
>
>
>
> I was wondering if you have any idea what could be causing this. Should the standard qemu be able
> to run mips16 executables with no changes?
I am fairly sure QEMU has issues with MIPS16 code, and I wouldn't be
surprised if user-mode emulation actually required porting QEMU, rather
than merely fixing bugs, to support MIPS16 binaries -- it may not be
prepared to handle the ISA bit at all.
Have you tried running your code on actual hardware? This is how we did
testing of all these changes.
Please also note that as I mentioned along the patch submission mixing
execution modes in static constructors or destructors installed as single
lumps of code (that is with the use of the DT_INIT or DT_FINI dynamic
tags) cannot be supported. Can you run `objdump -j .init -j .fini -d' on
your binary and make sure the disassembly looks right?
Here's an example of correct MIPS16 code from one of the test cases:
Disassembly of section .init:
00400a2c <_init>:
400a2c: f000 6a02 li v0,2
400a30: f692 0b10 la v1,3fa0c0 <_DYNAMIC-0x60dc>
400a34: f400 3240 sll v0,16
400a38: e269 addu v0,v1
400a3a: 64c4 save 32,ra
400a3c: 659a move gp,v0
400a3e: d204 sw v0,16(sp)
400a40: f030 9a6c lw v1,-32724(v0)
400a44: 2304 beqz v1,400a4e <_init+0x22>
400a46: f030 9a4c lw v0,-32724(v0)
400a4a: ea40 jalr v0
400a4c: 653a move t9,v0
400a4e: 6500 nop
400a50: 1a00 036e jal 400db8 <frame_dummy>
400a54: 6500 nop
400a56: 1a00 0400 jal 401000 <__do_global_ctors_aux>
400a5a: 6500 nop
400a5c: 6444 restore 32,ra
400a5e: e8a0 jrc ra
Disassembly of section .fini:
00401050 <_fini>:
401050: f000 6a02 li v0,2
401054: f072 0b0c la v1,3fa0c0 <_DYNAMIC-0x60dc>
401058: f400 3240 sll v0,16
40105c: e269 addu v0,v1
40105e: 64c4 save 32,ra
401060: 659a move gp,v0
401062: d204 sw v0,16(sp)
401064: 1a00 035a jal 400d68 <__do_global_dtors_aux>
401068: 6500 nop
40106a: 6444 restore 32,ra
40106c: e8a0 jrc ra
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-25 5:14 ` Maciej W. Rozycki
@ 2013-01-25 13:59 ` Richard Sandiford
2013-01-28 22:18 ` Steve Ellcey
2013-01-25 22:10 ` Steve Ellcey
1 sibling, 1 reply; 26+ messages in thread
From: Richard Sandiford @ 2013-01-25 13:59 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Ellcey, Steve, libc-alpha, libc-ports, Chung-Lin Tang
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
>> After some poking around I think the problem is not the glibc that I
>> built but with crti.o and crtn.o. If I use
>> regular mips32 versions of these crt files and mips16 built versions
>> of everything else (main program, glibc,
>> libgcc, etc.) then I can run a simple hello world program, if I use
>> the mips16 versions of crti and crtn I get:
>>
>>
>> mips-mti-linux-gnu-gcc -mips32r2 -mips16
>> -Wl,--dynamic-linker=/local/home/sellcey/gcc/mips16/sysroot-mips-mti-linux-gnu/mips16/usr/lib/ld-2.17.90.so'
>> -Wl,-rpath=/local/home/sellcey/gcc/mips16/sysroot-mips-mti-linux-gnu/mips16/usr/lib:/local/home/sellcey/gcc/mips16/install-mips-mti-linux-gnu/mips-mti-linux-gnu/lib/mips16'
>> hi.c -o x
>>
>> mips-mti-linux-gnu-qemu -r 2.6.38 ./x
>> hi
>> qemu: uncaught target signal 11 (Segmentation fault) - core dumped
>>
>> Note that it did print 'hi' before getting the signal.
>>
>> If I try adding '-static' then I get:
>>
>> mips-mti-linux-gnu-gcc -static -mips32r2 -mips16 hi.c -o x
>> mips-mti-linux-gnu-qemu -r 2.6.38 ./x
>> qemu: uncaught target signal 4 (Illegal instruction) - core dumped
>>
>>
>>
>> I was wondering if you have any idea what could be causing this.
>> Should the standard qemu be able
>> to run mips16 executables with no changes?
>
> I am fairly sure QEMU has issues with MIPS16 code, and I wouldn't be
> surprised if user-mode emulation actually required porting QEMU, rather
> than merely fixing bugs, to support MIPS16 binaries -- it may not be
> prepared to handle the ISA bit at all.
Never tried user-mode emulation either, but FWIW...
> Have you tried running your code on actual hardware? This is how we did
> testing of all these changes.
...QEMU 1.2 system emulation seems to handle MIPS16 pretty well,
so that might be another alternative. See:
http://gcc.gnu.org/ml/gcc-testresults/2013-01/msg02626.html
http://gcc.gnu.org/ml/gcc-testresults/2013-01/msg02550.html
for some recent results.
Richard
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-25 5:14 ` Maciej W. Rozycki
2013-01-25 13:59 ` Richard Sandiford
@ 2013-01-25 22:10 ` Steve Ellcey
2013-01-26 0:32 ` Maciej W. Rozycki
1 sibling, 1 reply; 26+ messages in thread
From: Steve Ellcey @ 2013-01-25 22:10 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: libc-alpha, libc-ports, Chung-Lin Tang
On Fri, 2013-01-25 at 05:13 +0000, Maciej W. Rozycki wrote:
> Have you tried running your code on actual hardware? This is how we did
> testing of all these changes.
I thought I had a simple program working on my 74K, but I just tried a
test case (hello world compiled statically) and it gave me a bus error.
> Please also note that as I mentioned along the patch submission mixing
> execution modes in static constructors or destructors installed as single
> lumps of code (that is with the use of the DT_INIT or DT_FINI dynamic
> tags) cannot be supported. Can you run `objdump -j .init -j .fini -d' on
> your binary and make sure the disassembly looks right?
Mine looks a bit different, this is the .init and .fini from a
dynamically linked big endian hello world program, I am not sure where
the addiu instructions are coming from.
x: file format elf32-tradbigmips
Disassembly of section .init:
004004d0 <_init>:
4004d0: f000 6a02 li v0,2
4004d4: f2f0 0b0c la v1,3f87c0 <_DYNAMIC-0x7a08>
4004d8: f400 3240 sll v0,16
4004dc: e269 addu v0,v1
4004de: 64c4 save 32,ra
4004e0: 659a move gp,v0
4004e2: d204 sw v0,16(sp)
4004e4: f030 9a64 lw v1,-32732(v0)
4004e8: 2304 beqz v1,4004f2 <_init+0x22>
4004ea: f030 9a44 lw v0,-32732(v0)
4004ee: ea40 jalr v0
4004f0: 653a move t9,v0
4004f2: 6500 nop
4004f4: 0411 addiu a0,sp,68
4004f6: 0001 addiu s0,sp,4
4004f8: 0000 addiu s0,sp,0
4004fa: 0000 addiu s0,sp,0
4004fc: 7410 cmpi a0,16
4004fe: 0196 addiu s1,sp,600
400500: 0000 addiu s0,sp,0
400502: 0000 addiu s0,sp,0
400504: 0411 addiu a0,sp,68
400506: 0001 addiu s0,sp,4
400508: 0000 addiu s0,sp,0
40050a: 0000 addiu s0,sp,0
40050c: 7410 cmpi a0,16
40050e: 01c0 addiu s1,sp,768
400510: 0000 addiu s0,sp,0
400512: 0000 addiu s0,sp,0
400514: 6444 restore 32,ra
400516: e8a0 jrc ra
Disassembly of section .fini:
00400730 <_fini>:
400730: f000 6a02 li v0,2
400734: f090 0b0c la v1,3f87c0 <_DYNAMIC-0x7a08>
400738: f400 3240 sll v0,16
40073c: e269 addu v0,v1
40073e: 64c4 save 32,ra
400740: 659a move gp,v0
400742: d204 sw v0,16(sp)
400744: 0411 addiu a0,sp,68
400746: 0001 addiu s0,sp,4
400748: 0000 addiu s0,sp,0
40074a: 0000 addiu s0,sp,0
40074c: 7410 cmpi a0,16
40074e: 0182 addiu s1,sp,520
400750: 0000 addiu s0,sp,0
400752: 0000 addiu s0,sp,0
400754: 6444 restore 32,ra
400756: e8a0 jrc ra
Steve Ellcey
sellcey@mips.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-25 22:10 ` Steve Ellcey
@ 2013-01-26 0:32 ` Maciej W. Rozycki
2013-01-28 17:36 ` Steve Ellcey
0 siblings, 1 reply; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-26 0:32 UTC (permalink / raw)
To: Steve Ellcey; +Cc: libc-alpha, libc-ports, Chung-Lin Tang
On Fri, 25 Jan 2013, Steve Ellcey wrote:
> > Please also note that as I mentioned along the patch submission mixing
> > execution modes in static constructors or destructors installed as single
> > lumps of code (that is with the use of the DT_INIT or DT_FINI dynamic
> > tags) cannot be supported. Can you run `objdump -j .init -j .fini -d' on
> > your binary and make sure the disassembly looks right?
>
> Mine looks a bit different, this is the .init and .fini from a
> dynamically linked big endian hello world program, I am not sure where
> the addiu instructions are coming from.
You have some standard MIPS code there, this is not ever going to work
unless we switch to DT_INIT_ARRAY and DT_FINI_ARRAY
constructors/destructors. Until then you need to rebuild the relevant
sources as MIPS16 code.
> x: file format elf32-tradbigmips
>
>
> Disassembly of section .init:
>
> 004004d0 <_init>:
> 4004d0: f000 6a02 li v0,2
> 4004d4: f2f0 0b0c la v1,3f87c0 <_DYNAMIC-0x7a08>
> 4004d8: f400 3240 sll v0,16
> 4004dc: e269 addu v0,v1
> 4004de: 64c4 save 32,ra
> 4004e0: 659a move gp,v0
> 4004e2: d204 sw v0,16(sp)
> 4004e4: f030 9a64 lw v1,-32732(v0)
> 4004e8: 2304 beqz v1,4004f2 <_init+0x22>
> 4004ea: f030 9a44 lw v0,-32732(v0)
> 4004ee: ea40 jalr v0
> 4004f0: 653a move t9,v0
> 4004f2: 6500 nop
> 4004f4: 0411 addiu a0,sp,68
> 4004f6: 0001 addiu s0,sp,4
> 4004f8: 0000 addiu s0,sp,0
> 4004fa: 0000 addiu s0,sp,0
> 4004fc: 7410 cmpi a0,16
> 4004fe: 0196 addiu s1,sp,600
> 400500: 0000 addiu s0,sp,0
> 400502: 0000 addiu s0,sp,0
> 400504: 0411 addiu a0,sp,68
> 400506: 0001 addiu s0,sp,4
> 400508: 0000 addiu s0,sp,0
> 40050a: 0000 addiu s0,sp,0
> 40050c: 7410 cmpi a0,16
> 40050e: 01c0 addiu s1,sp,768
> 400510: 0000 addiu s0,sp,0
> 400512: 0000 addiu s0,sp,0
> 400514: 6444 restore 32,ra
> 400516: e8a0 jrc ra
>
> Disassembly of section .fini:
>
> 00400730 <_fini>:
> 400730: f000 6a02 li v0,2
> 400734: f090 0b0c la v1,3f87c0 <_DYNAMIC-0x7a08>
> 400738: f400 3240 sll v0,16
> 40073c: e269 addu v0,v1
> 40073e: 64c4 save 32,ra
> 400740: 659a move gp,v0
> 400742: d204 sw v0,16(sp)
> 400744: 0411 addiu a0,sp,68
> 400746: 0001 addiu s0,sp,4
> 400748: 0000 addiu s0,sp,0
> 40074a: 0000 addiu s0,sp,0
> 40074c: 7410 cmpi a0,16
> 40074e: 0182 addiu s1,sp,520
> 400750: 0000 addiu s0,sp,0
> 400752: 0000 addiu s0,sp,0
> 400754: 6444 restore 32,ra
> 400756: e8a0 jrc ra
The odd instructions disassemble as follows when interpreted as standard
MIPS code:
0: 04110001 bal 8
4: 00000000 nop
8: 74100196 jalx 400658
c: 00000000 nop
10: 04110001 bal 18
14: 00000000 nop
18: 741001c0 jalx 400700
1c: 00000000 nop
and:
0: 04110001 bal 8
4: 00000000 nop
8: 74100182 jalx 400608
c: 00000000 nop
Make sure that you've got your GCC pieces of the MIPS16 multilib right
(crtbegin.o and crtend.o files).
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-26 0:32 ` Maciej W. Rozycki
@ 2013-01-28 17:36 ` Steve Ellcey
2013-01-28 17:56 ` Steve Ellcey
2013-01-28 18:58 ` Richard Henderson
0 siblings, 2 replies; 26+ messages in thread
From: Steve Ellcey @ 2013-01-28 17:36 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: libc-alpha, libc-ports, Chung-Lin Tang
On Sat, 2013-01-26 at 00:31 +0000, Maciej W. Rozycki wrote:
> On Fri, 25 Jan 2013, Steve Ellcey wrote:
>
> > > Please also note that as I mentioned along the patch submission mixing
> > > execution modes in static constructors or destructors installed as single
> > > lumps of code (that is with the use of the DT_INIT or DT_FINI dynamic
> > > tags) cannot be supported. Can you run `objdump -j .init -j .fini -d' on
> > > your binary and make sure the disassembly looks right?
> >
> > Mine looks a bit different, this is the .init and .fini from a
> > dynamically linked big endian hello world program, I am not sure where
> > the addiu instructions are coming from.
>
> You have some standard MIPS code there, this is not ever going to work
> unless we switch to DT_INIT_ARRAY and DT_FINI_ARRAY
> constructors/destructors. Until then you need to rebuild the relevant
> sources as MIPS16 code.
OK, I see where this is happening now. crti (from glibc) is mips16 and
crtbegin (from gcc) is mips32. crtbegin is mips32 because it uses
CRT_CALL_STATIC_FUNCTION and that has '.nomips16' in it. I am not sure
how to rewrite CRT_CALL_STATIC_FUNCTION in mips16 to avoid this and it
looks like the codesourcery version of GCC is handling this by making
all .init/.fini code mips32 instead of mips16. So, should I try to make
crti use a mips32 .init or make crtbegin use a mips16 .init? I am not
sure which is better.
Steve Ellcey
sellcey@mips.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-28 17:36 ` Steve Ellcey
@ 2013-01-28 17:56 ` Steve Ellcey
2013-01-28 21:08 ` Maciej W. Rozycki
2013-01-28 18:58 ` Richard Henderson
1 sibling, 1 reply; 26+ messages in thread
From: Steve Ellcey @ 2013-01-28 17:56 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: libc-alpha, libc-ports, Chung-Lin Tang
On Mon, 2013-01-28 at 09:35 -0800, Steve Ellcey wrote:
> OK, I see where this is happening now. crti (from glibc) is mips16 and
> crtbegin (from gcc) is mips32. crtbegin is mips32 because it uses
> CRT_CALL_STATIC_FUNCTION and that has '.nomips16' in it. I am not sure
> how to rewrite CRT_CALL_STATIC_FUNCTION in mips16 to avoid this and it
> looks like the codesourcery version of GCC is handling this by making
> all .init/.fini code mips32 instead of mips16. So, should I try to make
> crti use a mips32 .init or make crtbegin use a mips16 .init? I am not
> sure which is better.
>
> Steve Ellcey
> sellcey@mips.com
Following up to my own email, I think I was wrong about codesourcery
using mips32 code in .init/.fini, it looks like they have a GCC patch
to define CRT_CALL_STATIC_FUNCTION differently for mips16/mips32. I am
going to try and apply that patch to my ToT GCC and see what happens.
Steve Ellcey
sellcey@mips.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-28 17:36 ` Steve Ellcey
2013-01-28 17:56 ` Steve Ellcey
@ 2013-01-28 18:58 ` Richard Henderson
2013-01-28 21:06 ` Maciej W. Rozycki
1 sibling, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2013-01-28 18:58 UTC (permalink / raw)
To: Steve Ellcey; +Cc: Maciej W. Rozycki, libc-alpha, libc-ports, Chung-Lin Tang
On 01/28/2013 09:35 AM, Steve Ellcey wrote:
> OK, I see where this is happening now. crti (from glibc) is mips16 and
> crtbegin (from gcc) is mips32. crtbegin is mips32 because it uses
> CRT_CALL_STATIC_FUNCTION and that has '.nomips16' in it. I am not sure
> how to rewrite CRT_CALL_STATIC_FUNCTION in mips16 to avoid this and it
> looks like the codesourcery version of GCC is handling this by making
> all .init/.fini code mips32 instead of mips16. So, should I try to make
> crti use a mips32 .init or make crtbegin use a mips16 .init? I am not
> sure which is better.
FWIW, I think you're better off considering the .init section to be
mips32 code always, as a part of the ABI. That way stuff that worked
before continues to work, and no one has to worry about how the
installed toolchain itself is configured.
And of course as you note elsewhere, this is an excellent time to
have new toolchains stop using .init, as DT_INIT_ARRAY has none of
these problems.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-28 18:58 ` Richard Henderson
@ 2013-01-28 21:06 ` Maciej W. Rozycki
2013-01-28 21:17 ` Steve Ellcey
0 siblings, 1 reply; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-28 21:06 UTC (permalink / raw)
To: Richard Henderson; +Cc: Steve Ellcey, libc-alpha, libc-ports, Chung-Lin Tang
On Mon, 28 Jan 2013, Richard Henderson wrote:
> > OK, I see where this is happening now. crti (from glibc) is mips16 and
> > crtbegin (from gcc) is mips32. crtbegin is mips32 because it uses
> > CRT_CALL_STATIC_FUNCTION and that has '.nomips16' in it. I am not sure
> > how to rewrite CRT_CALL_STATIC_FUNCTION in mips16 to avoid this and it
> > looks like the codesourcery version of GCC is handling this by making
> > all .init/.fini code mips32 instead of mips16. So, should I try to make
> > crti use a mips32 .init or make crtbegin use a mips16 .init? I am not
> > sure which is better.
>
> FWIW, I think you're better off considering the .init section to be
> mips32 code always, as a part of the ABI. That way stuff that worked
> before continues to work, and no one has to worry about how the
> installed toolchain itself is configured.
That may work as a temporary measure for MIPS16 code only, as any
processor that supports MIPS16 execution must also support standard MIPS
execution.
However we have the very same problem with microMIPS code -- that glibc
supports out of the box thanks to the high level of source compatibility
the ISA provides and GCC support for which is currently under review.
There we cannot agree upon using standard MIPS code in .init/.fini because
we have conflicting objectives to choose from:
1. We want to support mixing standard MIPS and microMIPS code, so we
cannot assume all binary modules in a static link will use the same
encoding.
2. We want to support processors that only support either instruction
encoding, so the encoding of .init/.fini code has to match the encoding
of the remaining parts of the module concerned.
And regardless of the scenario chosen we want to keep the same binary
modules built for either ISA without the need to rebuild any parts of
them.
> And of course as you note elsewhere, this is an excellent time to
> have new toolchains stop using .init, as DT_INIT_ARRAY has none of
> these problems.
Given the above I think we need it sooner rather than later. Who's got
the power to make it happen?
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
* RE: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-28 17:56 ` Steve Ellcey
@ 2013-01-28 21:08 ` Maciej W. Rozycki
0 siblings, 0 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-01-28 21:08 UTC (permalink / raw)
To: Steve Ellcey; +Cc: libc-alpha, libc-ports, Chung-Lin Tang
On Mon, 28 Jan 2013, Steve Ellcey wrote:
> Following up to my own email, I think I was wrong about codesourcery
> using mips32 code in .init/.fini, it looks like they have a GCC patch
> to define CRT_CALL_STATIC_FUNCTION differently for mips16/mips32. I am
> going to try and apply that patch to my ToT GCC and see what happens.
Indeed, I wasn't aware there was an outstanding change there. Sorry
about that. I think for now our best option is to follow Richard's
suggestion. I'll take it into account with the upcoming patch update.
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-28 21:06 ` Maciej W. Rozycki
@ 2013-01-28 21:17 ` Steve Ellcey
2013-01-29 16:24 ` Richard Henderson
0 siblings, 1 reply; 26+ messages in thread
From: Steve Ellcey @ 2013-01-28 21:17 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: Richard Henderson, libc-alpha, libc-ports, Chung-Lin Tang, rdsandiford
On Mon, 2013-01-28 at 21:06 +0000, Maciej W. Rozycki wrote:
> On Mon, 28 Jan 2013, Richard Henderson wrote:
>
> > And of course as you note elsewhere, this is an excellent time to
> > have new toolchains stop using .init, as DT_INIT_ARRAY has none of
> > these problems.
>
> Given the above I think we need it sooner rather than later. Who's got
> the power to make it happen?
>
> Maciej
Would switching from .init to DT_INIT_ARRAY be an incompatible ABI
change? I think I remember the GNU linker can handle mixing both types
of sections in one executable but I am not sure if that is right.
I added Richard Sandiford to this email in case he hasn't seen it on the
libc mailing lists.
Steve Ellcey
sellcey@mips.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-25 13:59 ` Richard Sandiford
@ 2013-01-28 22:18 ` Steve Ellcey
0 siblings, 0 replies; 26+ messages in thread
From: Steve Ellcey @ 2013-01-28 22:18 UTC (permalink / raw)
To: Richard Sandiford
Cc: Maciej W. Rozycki, libc-alpha, libc-ports, Chung-Lin Tang
On Fri, 2013-01-25 at 13:59 +0000, Richard Sandiford wrote:
> "Maciej W. Rozycki" <macro@codesourcery.com> writes:
>
> Never tried user-mode emulation either, but FWIW...
>
> > Have you tried running your code on actual hardware? This is how we did
> > testing of all these changes.
>
> ...QEMU 1.2 system emulation seems to handle MIPS16 pretty well,
> so that might be another alternative. See:
>
> http://gcc.gnu.org/ml/gcc-testresults/2013-01/msg02626.html
> http://gcc.gnu.org/ml/gcc-testresults/2013-01/msg02550.html
>
> for some recent results.
>
> Richard
FYI: Now that I got my .init section straightened out with a patch to
GCC I was able to use qemu to test mips16. I ran the entire GCC
testsuite with -mips16 and the only failure I saw that didn't look
familiar to me was:
FAIL: gcc.c-torture/execute/ieee/compare-fp-1.c compilation, -O2 -flto
-fuse-linker-plugin -fno-fat-lto-objects
This is a segfault coming from the linker, I haven't investigated it
anymore then that yet, but in general the testing looks very good now.
Steve Ellcey
sellcey@mips.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-28 21:17 ` Steve Ellcey
@ 2013-01-29 16:24 ` Richard Henderson
2013-01-29 19:27 ` Joseph S. Myers
0 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2013-01-29 16:24 UTC (permalink / raw)
To: Steve Ellcey
Cc: Maciej W. Rozycki, libc-alpha, libc-ports, Chung-Lin Tang, rdsandiford
On 01/28/2013 01:17 PM, Steve Ellcey wrote:
> On Mon, 2013-01-28 at 21:06 +0000, Maciej W. Rozycki wrote:
>> On Mon, 28 Jan 2013, Richard Henderson wrote:
>>
>>> And of course as you note elsewhere, this is an excellent time to
>>> have new toolchains stop using .init, as DT_INIT_ARRAY has none of
>>> these problems.
>>
>> Given the above I think we need it sooner rather than later. Who's got
>> the power to make it happen?
>>
>> Maciej
>
> Would switching from .init to DT_INIT_ARRAY be an incompatible ABI
> change? I think I remember the GNU linker can handle mixing both types
> of sections in one executable but I am not sure if that is right.
>
> I added Richard Sandiford to this email in case he hasn't seen it on the
> libc mailing lists.
Both gcc and ld have an --enable-initfini-array configuration switch.
Both programs can autodetect the current host setting during native
builds to preserve the system setting.
I don't believe there's currently a way to force the setting on based on
a configuration triple, but it ought not be hard to add.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/2] MIPS16: MIPS16 support proper
2013-01-29 16:24 ` Richard Henderson
@ 2013-01-29 19:27 ` Joseph S. Myers
0 siblings, 0 replies; 26+ messages in thread
From: Joseph S. Myers @ 2013-01-29 19:27 UTC (permalink / raw)
To: Richard Henderson
Cc: Steve Ellcey, Maciej W. Rozycki, libc-alpha, libc-ports,
Chung-Lin Tang, rdsandiford
On Tue, 29 Jan 2013, Richard Henderson wrote:
> Both gcc and ld have an --enable-initfini-array configuration switch.
>
> Both programs can autodetect the current host setting during native builds to
> preserve the system setting.
>
> I don't believe there's currently a way to force the setting on based on a
> configuration triple, but it ought not be hard to add.
FWIW, ARM EABI has used init_array/fini_array for a long time (probably
since before this configure option existed, and maybe not using the same
mechanism as the configure option), following an EABI requirement (which
might have been motivated by Thumb causing the same issues for .init/.fini
as MIPS16 and microMIPS).
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2] MIPS: MIPS16 support
2013-01-23 17:22 ` Joseph S. Myers
2013-01-24 10:10 ` Chung-Lin Tang
@ 2013-02-20 16:19 ` Maciej W. Rozycki
2013-02-20 16:29 ` Joseph S. Myers
1 sibling, 1 reply; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-02-20 16:19 UTC (permalink / raw)
To: Joseph S. Myers
Cc: libc-ports, Chung-Lin Tang, Steve Ellcey, Richard Sandiford
Joseph,
Here's an updated version of the change to add MIPS16 support to GNU
libc. I hope I have addressed all your concerns to your satisfaction.
MIPS16 CRT files have now been dropped and likewise the GCC change I used
for MIPS16 support there and I have bootstrapped the whole toolchain to
make sure the new arrangement still works as expected.
Also GLIBC_2.18 has been defined meanwhile, so I dropped the Versions.def
change, and consequently the patch does not require any attention at the
libc-alpha list anymore.
Like the original the update was regression-tested successfully for the
following configurations (compiler flag/multilib options), for both
endiannesses each (the -EB and -EL compiler option, respectively):
* 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),
with the MIPS32r2 or MIPS64r2 ISA level selected as applicable. Likewise
new functionality has been tested for:
* MIPS16 ISA, o32 (-mips16 -mabi=32),
* MIPS16 ISA, o32, soft-float (-mips16 -mabi=32 -msoft-float),
producing no failures other to ones already present for the standard MIPS
and microMIPS ISAs.
OK to apply?
2013-02-20 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.
(RTLD_START): Likewise.
* sysdeps/mips/fpu_control.h (__fpu_getcw) [__mips16]: New
prototype.
(__fpu_setcw) [__mips16]: 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.
* sysdeps/mips/bits/atomic.h
(atomic_compare_and_exchange_val_acq) [__mips16]: Likewise.
(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.
(TLS_GD, TLS_LD, TLS_IE, TLS_LE) [__mips16]: Likewise.
* sysdeps/mips/sys/tas.h (_test_and_set): Add `.set nomips16'.
* sysdeps/unix/mips/sysdep.h (PSEUDO_NOERRNO): Likewise.
(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/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): Add MIPS16 version.
* 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 nomips16.
(__longjmp): New alias.
* sysdeps/mips/dl-trampoline.c (_dl_runtime_resolve): Add MIPS16
version.
(_dl_runtime_pltresolve): Likewise.
* sysdeps/mips/setjmp_aux.c (__sigsetjmp_aux): Add nomips16
attribute.
* sysdeps/mips/fpu/e_sqrt.c (__ieee754_sqrt): Add nomips16
attribute.
* sysdeps/mips/fpu/e_sqrtf.c (__ieee754_sqrtf): Likewise.
* sysdeps/unix/sysv/linux/mips/brk.c (__brk): Replace inline asm
with INTERNAL_SYSCALL.
* sysdeps/mips/mips32/fpu/Implies: New file.
* 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/mips/mips32/mips16/Makefile: New file.
* sysdeps/mips/mips32/mips16/fpu/Makefile: New file.
* sysdeps/mips/mips32/mips16/fpu/Versions: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h:
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/unix/sysv/linux/mips/mips32/mips16/Makefile: New file.
* sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions: New file.
* sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist
(GLIBC_2.18): Add __fpu_getcw and __fpu_setcw.
* sysdeps/mips/preconfigure: Handle o32 MIPS16 compilation.
Maciej
glibc-mips16-upstream.diff
Index: ports/sysdeps/mips/__longjmp.c
===================================================================
--- ports/sysdeps/mips/__longjmp.c 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/__longjmp.c 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/abort-instr.h
===================================================================
--- ports/sysdeps/mips/abort-instr.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/abort-instr.h 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/bits/atomic.h
===================================================================
--- ports/sysdeps/mips/bits/atomic.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/bits/atomic.h 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/bsd-_setjmp.S
===================================================================
--- ports/sysdeps/mips/bsd-_setjmp.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/bsd-_setjmp.S 2013-02-19 22:23:55.317751073 +0000
@@ -26,6 +26,7 @@
.option pic2
#endif
ENTRY (_setjmp)
+ .set nomips16
#ifdef __PIC__
.set noreorder
.cpload t9
Index: ports/sysdeps/mips/bsd-setjmp.S
===================================================================
--- ports/sysdeps/mips/bsd-setjmp.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/bsd-setjmp.S 2013-02-19 22:23:55.317751073 +0000
@@ -26,6 +26,7 @@
.option pic2
#endif
ENTRY (setjmp)
+ .set nomips16
.set noreorder
#ifdef __PIC__
.cpload t9
Index: ports/sysdeps/mips/dl-machine.h
===================================================================
--- ports/sysdeps/mips/dl-machine.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/dl-machine.h 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/dl-trampoline.c
===================================================================
--- ports/sysdeps/mips/dl-trampoline.c 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/dl-trampoline.c 2013-02-19 22:23:55.317751073 +0000
@@ -292,8 +292,10 @@ __dl_runtime_resolve (ElfW(Word) sym_ind
#endif
+#ifndef __mips16
asm ("\n\
.text\n\
+ .set nomips16\n\
.align 2\n\
.globl _dl_runtime_resolve\n\
.type _dl_runtime_resolve,@function\n\
@@ -350,6 +352,7 @@ _dl_runtime_resolve:\n\
asm ("\n\
.text\n\
+ .set nomips16\n\
.align 2\n\
.globl _dl_runtime_pltresolve\n\
.type _dl_runtime_pltresolve,@function\n\
@@ -381,3 +384,130 @@ _dl_runtime_pltresolve:\n\
.previous\n\
");
+#elif _MIPS_SIM == _ABIO32 /* __mips16 */
+/* MIPS16 version, O32 only. */
+asm ("\n\
+ .text\n\
+ .set mips16\n\
+ .align 2\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\
+ .set mips16\n\
+ .align 2\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: ports/sysdeps/mips/fpu/e_sqrt.c
===================================================================
--- ports/sysdeps/mips/fpu/e_sqrt.c 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/fpu/e_sqrt.c 2013-02-19 22:23:55.317751073 +0000
@@ -22,7 +22,7 @@
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
-double
+double __attribute__ ((nomips16))
__ieee754_sqrt (double x)
{
double z;
Index: ports/sysdeps/mips/fpu/e_sqrtf.c
===================================================================
--- ports/sysdeps/mips/fpu/e_sqrtf.c 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/fpu/e_sqrtf.c 2013-02-19 22:23:55.317751073 +0000
@@ -22,7 +22,7 @@
#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
-float
+float __attribute__ ((nomips16))
__ieee754_sqrtf (float x)
{
float z;
Index: ports/sysdeps/mips/fpu_control.h
===================================================================
--- ports/sysdeps/mips/fpu_control.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/fpu_control.h 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/machine-gmon.h
===================================================================
--- ports/sysdeps/mips/machine-gmon.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/machine-gmon.h 2013-02-19 22:23:55.317751073 +0000
@@ -35,6 +35,8 @@ static void __attribute_used__ __mcount
#endif
#define MCOUNT asm(\
+ ".set push;\n\t" \
+ ".set nomips16;\n\t" \
".globl _mcount;\n\t" \
".align 2;\n\t" \
".type _mcount,@function;\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
@@ -92,6 +93,8 @@ static void __attribute_used__ __mcount
#endif
#define MCOUNT asm(\
+ ".set push;\n\t" \
+ ".set nomips16;\n\t" \
".globl _mcount;\n\t" \
".align 3;\n\t" \
".type _mcount,@function;\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: ports/sysdeps/mips/memset.S
===================================================================
--- ports/sysdeps/mips/memset.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/memset.S 2013-02-19 22:23:55.317751073 +0000
@@ -28,6 +28,7 @@
#endif
ENTRY (memset)
+ .set nomips16
.set noreorder
slti t1, a2, 8 # Less than 8?
Index: ports/sysdeps/mips/mips32/crti.S
===================================================================
--- ports/sysdeps/mips/mips32/crti.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/mips32/crti.S 2013-02-19 22:23:55.317751073 +0000
@@ -54,6 +54,8 @@
.hidden PREINIT_FUNCTION
#endif
+ .set nomips16
+
.section .init,"ax",@progbits
.p2align 2
.globl _init
Index: ports/sysdeps/mips/mips32/crtn.S
===================================================================
--- ports/sysdeps/mips/mips32/crtn.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/mips32/crtn.S 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/mips32/fpu/Versions
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/fpu/Versions 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1,5 @@
+libc {
+ GLIBC_2.18 {
+ __fpu_getcw; __fpu_getcw;
+ }
+}
Index: ports/sysdeps/mips/mips32/fpu/fpu_control.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/fpu/fpu_control.c 2013-02-19 22:23:55.317751073 +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
+ <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);
+}
Index: ports/sysdeps/mips/mips32/mips16/add_n.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/add_n.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/add_n.c>
Index: ports/sysdeps/mips/mips32/mips16/addmul_1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/addmul_1.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/addmul_1.c>
Index: ports/sysdeps/mips/mips32/mips16/fpu/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/fpu/Makefile 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/mips32/mips16/lshift.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/lshift.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/lshift.c>
Index: ports/sysdeps/mips/mips32/mips16/mul_1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/mul_1.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/mul_1.c>
Index: ports/sysdeps/mips/mips32/mips16/rshift.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/rshift.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/rshift.c>
Index: ports/sysdeps/mips/mips32/mips16/sub_n.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/sub_n.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/sub_n.c>
Index: ports/sysdeps/mips/mips32/mips16/submul_1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/mips/mips32/mips16/submul_1.c 2013-02-19 22:23:55.317751073 +0000
@@ -0,0 +1 @@
+#include <stdlib/submul_1.c>
Index: ports/sysdeps/mips/mips64/n32/crti.S
===================================================================
--- ports/sysdeps/mips/mips64/n32/crti.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/mips64/n32/crti.S 2013-02-19 22:23:55.317751073 +0000
@@ -54,6 +54,8 @@
.hidden PREINIT_FUNCTION
#endif
+ .set nomips16
+
.section .init,"ax",@progbits
.p2align 2
.globl _init
Index: ports/sysdeps/mips/mips64/n32/crtn.S
===================================================================
--- ports/sysdeps/mips/mips64/n32/crtn.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/mips64/n32/crtn.S 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/mips64/n64/crti.S
===================================================================
--- ports/sysdeps/mips/mips64/n64/crti.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/mips64/n64/crti.S 2013-02-19 22:23:55.317751073 +0000
@@ -54,6 +54,8 @@
.hidden PREINIT_FUNCTION
#endif
+ .set nomips16
+
.section .init,"ax",@progbits
.p2align 2
.globl _init
Index: ports/sysdeps/mips/mips64/n64/crtn.S
===================================================================
--- ports/sysdeps/mips/mips64/n64/crtn.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/mips64/n64/crtn.S 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/nptl/tls.h
===================================================================
--- ports/sysdeps/mips/nptl/tls.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/nptl/tls.h 2013-02-19 22:23:55.317751073 +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 <tcb-offsets.h>
Index: ports/sysdeps/mips/preconfigure
===================================================================
--- ports/sysdeps/mips/preconfigure 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/preconfigure 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/setjmp.S
===================================================================
--- ports/sysdeps/mips/setjmp.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/setjmp.S 2013-02-19 22:23:55.317751073 +0000
@@ -24,6 +24,7 @@
.option pic2
#endif
ENTRY (__sigsetjmp)
+ .set nomips16
#ifdef __PIC__
.set noreorder
.cpload t9
Index: ports/sysdeps/mips/setjmp_aux.c
===================================================================
--- ports/sysdeps/mips/setjmp_aux.c 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/setjmp_aux.c 2013-02-19 22:23:55.317751073 +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: ports/sysdeps/mips/start.S
===================================================================
--- ports/sysdeps/mips/start.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/start.S 2013-02-19 22:23:55.327333248 +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. */
+ENTRY_POINT:
+ .set mips16
+# 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: ports/sysdeps/mips/sys/tas.h
===================================================================
--- ports/sysdeps/mips/sys/tas.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/sys/tas.h 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/mips/tls-macros.h
===================================================================
--- ports/sysdeps/mips/tls-macros.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/mips/tls-macros.h 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/unix/mips/mips32/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/mips32/sysdep.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/mips/mips32/sysdep.h 2013-02-19 22:23:55.327333248 +0000
@@ -23,6 +23,7 @@
backwards into the previous fn. */
#ifdef __PIC__
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.align 2; \
cfi_startproc; \
99: la t9,__syscall_error; \
@@ -38,6 +39,7 @@
L(syse1):
#else
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.set noreorder; \
.align 2; \
cfi_startproc; \
Index: ports/sysdeps/unix/mips/mips64/n32/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/mips64/n32/sysdep.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/mips/mips64/n32/sysdep.h 2013-02-19 22:23:55.327333248 +0000
@@ -25,6 +25,7 @@
backwards into the previous fn. */
#ifdef __PIC__
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.align 2; \
cfi_startproc; \
99:; \
@@ -44,6 +45,7 @@
L(syse1):
#else
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.set noreorder; \
.align 2; \
cfi_startproc; \
Index: ports/sysdeps/unix/mips/mips64/n64/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/mips64/n64/sysdep.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/mips/mips64/n64/sysdep.h 2013-02-19 22:23:55.327333248 +0000
@@ -25,6 +25,7 @@
backwards into the previous fn. */
#ifdef __PIC__
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.align 2; \
cfi_startproc; \
99:; \
@@ -44,6 +45,7 @@
L(syse1):
#else
#define PSEUDO(name, syscall_name, args) \
+ .set nomips16; \
.set noreorder; \
.align 2; \
cfi_startproc; \
Index: ports/sysdeps/unix/mips/sysdep.S
===================================================================
--- ports/sysdeps/unix/mips/sysdep.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/mips/sysdep.S 2013-02-19 22:23:55.327333248 +0000
@@ -21,6 +21,8 @@
#include <bits/errno.h>
#include <sys/asm.h>
+ .set nomips16
+
#ifdef _LIBC_REENTRANT
LOCALSZ= 3
Index: ports/sysdeps/unix/mips/sysdep.h
===================================================================
--- ports/sysdeps/unix/mips/sysdep.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/mips/sysdep.h 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/unix/sysv/linux/mips/brk.c
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/brk.c 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/brk.c 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/unix/sysv/linux/mips/clone.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/clone.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/clone.S 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/unix/sysv/linux/mips/getcontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/getcontext.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/getcontext.S 2013-02-19 22:23:55.327333248 +0000
@@ -27,6 +27,7 @@
/* int getcontext (ucontext_t *ucp) */
.text
+ .set nomips16
LOCALSZ = 0
MASK = 0x00000000
#ifdef __PIC__
Index: ports/sysdeps/unix/sysv/linux/mips/makecontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/makecontext.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/makecontext.S 2013-02-19 22:23:55.327333248 +0000
@@ -27,6 +27,7 @@
/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */
.text
+ .set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Makefile 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/Versions 2013-02-19 22:23:55.327333248 +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: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h 2013-02-19 22:23:55.327333248 +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
+ <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
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall5.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall6.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall7.c 2013-02-19 22:23:55.327333248 +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
+ <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;
+}
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist 2013-02-19 22:23:55.327333248 +0000
@@ -2253,3 +2253,5 @@ GLIBC_2.17
GLIBC_2.18
GLIBC_2.18 A
__cxa_thread_atexit_impl F
+ __fpu_getcw F
+ __fpu_setcw F
Index: ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h 2013-02-19 22:23:55.327333248 +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 <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; \
Index: ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h 2013-02-19 22:23:55.327333248 +0000
@@ -45,6 +45,7 @@
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.align 2; \
+ .set nomips16; \
L(pseudo_start): \
cfi_startproc; \
99: PSEUDO_ERRJMP \
Index: ports/sysdeps/unix/sysv/linux/mips/setcontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/setcontext.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/setcontext.S 2013-02-19 22:23:55.327333248 +0000
@@ -27,6 +27,7 @@
/* int setcontext (const ucontext_t *ucp) */
.text
+ .set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000
Index: ports/sysdeps/unix/sysv/linux/mips/swapcontext.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/swapcontext.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/swapcontext.S 2013-02-19 22:23:55.327333248 +0000
@@ -27,6 +27,7 @@
/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
.text
+ .set nomips16
LOCALSZ = 0
ARGSZ = 0
MASK = 0x00000000
Index: ports/sysdeps/unix/sysv/linux/mips/vfork.S
===================================================================
--- ports/sysdeps/unix/sysv/linux/mips/vfork.S 2013-02-19 22:23:49.556613890 +0000
+++ ports/sysdeps/unix/sysv/linux/mips/vfork.S 2013-02-19 22:23:55.327333248 +0000
@@ -34,6 +34,7 @@
/* int vfork() */
.text
+ .set nomips16
LOCALSZ= 1
FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
GPOFF= FRAMESZ-(1*SZREG)
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2] MIPS: MIPS16 support
2013-02-20 16:19 ` [PATCH v2] MIPS: MIPS16 support Maciej W. Rozycki
@ 2013-02-20 16:29 ` Joseph S. Myers
2013-02-27 1:38 ` [PATCH v3] " Maciej W. Rozycki
0 siblings, 1 reply; 26+ messages in thread
From: Joseph S. Myers @ 2013-02-20 16:29 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: libc-ports, Chung-Lin Tang, Steve Ellcey, Richard Sandiford
On Wed, 20 Feb 2013, Maciej W. Rozycki wrote:
> * sysdeps/mips/fpu_control.h (__fpu_getcw) [__mips16]: New
> prototype.
> (__fpu_setcw) [__mips16]: Likewise.
Since you've renamed the functions to __mips_fpu_getcw and
__mips_fpu_setcw, you need to update the ChangeLog entry accordingly.
The ChangeLog entries may also need updates for other changes in this
patch version.
> * sysdeps/mips/mips32/mips16/fpu/Versions: New file.
Actually you moved the Versions file to the correct place for the symbol
versions not to depend on whether glibc itself is built as MIPS16. But
the contents of the file - and of the libc.abilist changes - need updating
for the new symbol names.
(Given these inconsistencies, I haven't fully reviewed the rest of the
patch contents.)
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v3] MIPS: MIPS16 support
2013-02-20 16:29 ` Joseph S. Myers
@ 2013-02-27 1:38 ` Maciej W. Rozycki
2013-02-27 17:50 ` Joseph S. Myers
0 siblings, 1 reply; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-02-27 1:38 UTC (permalink / raw)
To: Joseph S. Myers
Cc: libc-ports, Chung-Lin Tang, Steve Ellcey, Richard Sandiford
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 <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.
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 <sysdep.h>
+ .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 <sysdep.h>
+ .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 <sysdep.h>
+ .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
+ <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);
+}
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 <stdlib/add_n.c>
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 <stdlib/addmul_1.c>
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 <stdlib/lshift.c>
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 <stdlib/mul_1.c>
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 <stdlib/rshift.c>
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 <stdlib/sub_n.c>
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 <stdlib/submul_1.c>
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 <tcb-offsets.h>
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 <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. */
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 <bits/errno.h>
#include <sys/asm.h>
+ .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
+ <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
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
+ <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;
+}
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
+ <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;
+}
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
+ <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;
+}
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
+ <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;
+}
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
+ <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;
+}
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
+ <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;
+}
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
+ <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;
+}
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
+ <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;
+}
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 <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; \
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)
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3] MIPS: MIPS16 support
2013-02-27 1:38 ` [PATCH v3] " Maciej W. Rozycki
@ 2013-02-27 17:50 ` Joseph S. Myers
2013-02-27 23:54 ` Maciej W. Rozycki
0 siblings, 1 reply; 26+ messages in thread
From: Joseph S. Myers @ 2013-02-27 17:50 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: libc-ports, Chung-Lin Tang, Steve Ellcey, Richard Sandiford
On Wed, 27 Feb 2013, Maciej W. Rozycki wrote:
> OK to apply?
This patch version is OK.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3] MIPS: MIPS16 support
2013-02-27 17:50 ` Joseph S. Myers
@ 2013-02-27 23:54 ` Maciej W. Rozycki
0 siblings, 0 replies; 26+ messages in thread
From: Maciej W. Rozycki @ 2013-02-27 23:54 UTC (permalink / raw)
To: Joseph S. Myers
Cc: libc-ports, Chung-Lin Tang, Steve Ellcey, Richard Sandiford
On Wed, 27 Feb 2013, Joseph S. Myers wrote:
> > OK to apply?
>
> This patch version is OK.
Applied now, thanks for going through this review.
Maciej
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2013-02-27 23:54 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-23 4:41 [PATCH 0/2] MIPS16: MIPS16 support Maciej W. Rozycki
2013-01-23 4:41 ` [PATCH 1/2] MIPS16: Allocate GLIBC_2.18 Maciej W. Rozycki
2013-01-23 4:42 ` [PATCH 2/2] MIPS16: MIPS16 support proper Maciej W. Rozycki
2013-01-23 17:22 ` Joseph S. Myers
2013-01-24 10:10 ` Chung-Lin Tang
2013-01-24 13:13 ` Maciej W. Rozycki
2013-01-24 13:56 ` Richard Sandiford
2013-02-20 16:19 ` [PATCH v2] MIPS: MIPS16 support Maciej W. Rozycki
2013-02-20 16:29 ` Joseph S. Myers
2013-02-27 1:38 ` [PATCH v3] " Maciej W. Rozycki
2013-02-27 17:50 ` Joseph S. Myers
2013-02-27 23:54 ` Maciej W. Rozycki
2013-01-24 18:08 ` [PATCH 2/2] MIPS16: MIPS16 support proper Ellcey, Steve
2013-01-25 5:14 ` Maciej W. Rozycki
2013-01-25 13:59 ` Richard Sandiford
2013-01-28 22:18 ` Steve Ellcey
2013-01-25 22:10 ` Steve Ellcey
2013-01-26 0:32 ` Maciej W. Rozycki
2013-01-28 17:36 ` Steve Ellcey
2013-01-28 17:56 ` Steve Ellcey
2013-01-28 21:08 ` Maciej W. Rozycki
2013-01-28 18:58 ` Richard Henderson
2013-01-28 21:06 ` Maciej W. Rozycki
2013-01-28 21:17 ` Steve Ellcey
2013-01-29 16:24 ` Richard Henderson
2013-01-29 19:27 ` Joseph S. Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).