summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-02-04 13:51:21 +0000
committerEric Andersen <andersen@codepoet.org>2002-02-04 13:51:21 +0000
commit473a7dd3d8c4ae64956db05872e35a0336f447ab (patch)
treecfa6fdefe00b6559d6518546aab56a43fad1a17a /libc/sysdeps/linux
parent330eb7bad0aeb0f95a12eb77791bdb4b828249d4 (diff)
Fixup mips so it now works and provides basic functionality
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/mips/Makefile16
-rw-r--r--libc/sysdeps/linux/mips/__longjmp.c84
-rw-r--r--libc/sysdeps/linux/mips/brk.c49
-rw-r--r--libc/sysdeps/linux/mips/bsd-_setjmp.S49
-rw-r--r--libc/sysdeps/linux/mips/bsd-setjmp.S49
-rw-r--r--libc/sysdeps/linux/mips/clone.S107
-rw-r--r--libc/sysdeps/linux/mips/crt0.S50
-rw-r--r--libc/sysdeps/linux/mips/crt0.c60
-rw-r--r--libc/sysdeps/linux/mips/fork.S31
-rw-r--r--libc/sysdeps/linux/mips/regdef.h61
-rw-r--r--libc/sysdeps/linux/mips/setjmp.S53
11 files changed, 535 insertions, 74 deletions
diff --git a/libc/sysdeps/linux/mips/Makefile b/libc/sysdeps/linux/mips/Makefile
index 51f75caeb..b0bc87297 100644
--- a/libc/sysdeps/linux/mips/Makefile
+++ b/libc/sysdeps/linux/mips/Makefile
@@ -21,27 +21,19 @@
# other sundry sources. Files within this library are copyright by their
# respective copyright holders.
-USE_CRT0_C=y
-
TOPDIR=../../../../
include $(TOPDIR)Rules.mak
ASFLAGS=$(CFLAGS)
TARGET_MACHINE_TYPE=$(shell $(CC) -dumpmachine)
-ifeq ($(USE_CRT0_C),y)
-CRT0=crt0.c
-CRT0_OBJ=$(patsubst %.c,%.o, $(CRT0))
-else
CRT0=crt0.S
CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0))
-endif
-#SSRC=longjmp.S setjmp.S vfork.S
-SSRC=
+SSRC=bsd-_setjmp.S bsd-setjmp.S setjmp.S #fork.S clone.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=
+CSRC=__longjmp.c brk.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(MOBJ) $(COBJS)
@@ -56,11 +48,7 @@ ar-target: $(OBJS) $(CRT0_OBJ)
cp $(CRT0_OBJ) $(TOPDIR)libc
-ifeq ($(USE_CRT0_C),y)
-$(CRT0_OBJ): %.o : %.c
-else
$(CRT0_OBJ): %.o : %.S
-endif
$(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
diff --git a/libc/sysdeps/linux/mips/__longjmp.c b/libc/sysdeps/linux/mips/__longjmp.c
new file mode 100644
index 000000000..750a71fd1
--- /dev/null
+++ b/libc/sysdeps/linux/mips/__longjmp.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1992, 1995, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Brendan Kehoe (brendan@zen.org).
+
+ 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 <setjmp.h>
+#include <stdlib.h>
+
+#undef __longjmp
+
+#ifndef __GNUC__
+ #error This file uses GNU C extensions; you must compile with GCC.
+#endif
+
+void
+__longjmp (env, val_arg)
+ __jmp_buf env;
+ int val_arg;
+{
+ /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before
+ the hack around it); force it to use $a1 for the longjmp value.
+ Without this it saves $a1 in a register which gets clobbered
+ along the way. */
+ register int val asm ("a1");
+
+ /* Pull back the floating point callee-saved registers. */
+ asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
+ asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1]));
+ asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[2]));
+ asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3]));
+ asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
+ asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
+
+ /* Get and reconstruct the floating point csr. */
+ asm volatile ("lw $2, %0" : : "m" (env[0].__fpc_csr));
+ asm volatile ("ctc1 $2, $31");
+
+ /* Get the GP. */
+ asm volatile ("lw $gp, %0" : : "m" (env[0].__gp));
+
+ /* Get the callee-saved registers. */
+ asm volatile ("lw $16, %0" : : "m" (env[0].__regs[0]));
+ asm volatile ("lw $17, %0" : : "m" (env[0].__regs[1]));
+ asm volatile ("lw $18, %0" : : "m" (env[0].__regs[2]));
+ asm volatile ("lw $19, %0" : : "m" (env[0].__regs[3]));
+ asm volatile ("lw $20, %0" : : "m" (env[0].__regs[4]));
+ asm volatile ("lw $21, %0" : : "m" (env[0].__regs[5]));
+ asm volatile ("lw $22, %0" : : "m" (env[0].__regs[6]));
+ asm volatile ("lw $23, %0" : : "m" (env[0].__regs[7]));
+
+ /* Get the PC. */
+ asm volatile ("lw $25, %0" : : "m" (env[0].__pc));
+
+ /* Restore the stack pointer and the FP. They have to be restored
+ last and in a single asm as gcc, depending on options used, may
+ use either of them to access env. */
+ asm volatile ("lw $29, %0\n\t"
+ "lw $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
+
+/* Give setjmp 1 if given a 0, or what they gave us if non-zero. */
+ if (val == 0)
+ asm volatile ("li $2, 1");
+ else
+ asm volatile ("move $2, %0" : : "r" (val));
+
+ asm volatile ("jr $25");
+
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/libc/sysdeps/linux/mips/brk.c b/libc/sysdeps/linux/mips/brk.c
new file mode 100644
index 000000000..15026e102
--- /dev/null
+++ b/libc/sysdeps/linux/mips/brk.c
@@ -0,0 +1,49 @@
+/* brk system call for Linux/MIPS.
+ Copyright (C) 2000 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+void *__curbrk = 0;
+
+int __brk (void *addr)
+{
+ void *newbrk;
+
+ {
+ register long int res __asm__ ("$2");
+
+ asm ("move\t$4,%2\n\t"
+ "syscall" /* Perform the system call. */
+ : "=r" (res)
+ : "0" (__NR_brk), "r" (addr)
+ : "$4", "$7");
+ newbrk = (void *) res;
+ }
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/linux/mips/bsd-_setjmp.S b/libc/sysdeps/linux/mips/bsd-_setjmp.S
new file mode 100644
index 000000000..6a8391868
--- /dev/null
+++ b/libc/sysdeps/linux/mips/bsd-_setjmp.S
@@ -0,0 +1,49 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. MIPS version.
+ Copyright (C) 1996, 1997, 2000 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include "regdef.h"
+
+#ifdef __PIC__
+ .option pic2
+#endif
+
+.text
+.global _setjmp
+.align 2;
+.ent _setjmp,0;
+.type _setjmp,@function
+
+_setjmp:
+#ifdef __PIC__
+ .set noreorder
+ .cpload t9
+ .set reorder
+ la t9, __sigsetjmp
+#endif
+ move a1,zero /* Pass a second argument of zero. */
+#ifdef __PIC__
+ jr t9
+#else
+ j __sigsetjmp
+#endif
+ .end _setjmp;
diff --git a/libc/sysdeps/linux/mips/bsd-setjmp.S b/libc/sysdeps/linux/mips/bsd-setjmp.S
new file mode 100644
index 000000000..9539d652d
--- /dev/null
+++ b/libc/sysdeps/linux/mips/bsd-setjmp.S
@@ -0,0 +1,49 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. MIPS version.
+ Copyright (C) 1996, 1997, 2000 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include "regdef.h"
+
+#ifdef __PIC__
+ .option pic2
+#endif
+
+.text
+.global setjmp
+.align 2;
+.ent setjmp,0;
+.type setjmp,@function
+
+setjmp:
+ .set noreorder
+#ifdef __PIC__
+ .cpload t9
+ .set reorder
+ la t9, __sigsetjmp
+#endif
+ li a1, 1 /* Pass a second argument of one. */
+#ifdef __PIC__
+ jr t9
+#else
+ j __sigsetjmp
+#endif
+ .end setjmp
diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S
new file mode 100644
index 000000000..6f6a6c5b7
--- /dev/null
+++ b/libc/sysdeps/linux/mips/clone.S
@@ -0,0 +1,107 @@
+/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>, 1996.
+
+ 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. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <asm/unistd.h>
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
+
+ .text
+NESTED(__clone,4*SZREG,sp)
+#ifdef __PIC__
+ .set noreorder
+ .cpload $25
+ .set reorder
+ subu sp,32
+ .cprestore 16
+#else
+ subu sp,32
+#endif
+#ifdef PROF
+ .set noat
+ move $1,ra
+ jal _mcount
+ .set at
+#endif
+
+
+ /* Sanity check arguments. */
+ li v0,EINVAL
+ beqz a0,error /* No NULL function pointers. */
+ beqz a1,error /* No NULL stack pointers. */
+
+ subu a1,32 /* Reserve argument save space. */
+ sw a0,0(a1) /* Save function pointer. */
+ sw a3,4(a1) /* Save argument pointer. */
+
+
+ /* Do the system call */
+ move a0,a2
+ li v0,__NR_clone
+ syscall
+
+ bnez a3,error
+ beqz v0,__thread_start
+
+ /* Successful return from the parent */
+ addiu sp,32
+ ret
+
+ /* Something bad happened -- no child created */
+error:
+ addiu sp,32
+#ifdef __PIC__
+ la t9,__syscall_error
+ jr t9
+#else
+ j __syscall_error
+#endif
+ END(__clone)
+
+/* Load up the arguments to the function. Put this block of code in
+ its own function so that we can terminate the stack trace with our
+ debug info. */
+
+ENTRY(__thread_start)
+ /* cp is already loaded. */
+ .cprestore 16
+ /* The stackframe has been created on entry of clone(). */
+ /* Restore the arg for user's function. */
+ lw t9,0(sp) /* Function pointer. */
+ lw a0,4(sp) /* Argument pointer. */
+
+ /* Call the user's function. */
+ jalr t9
+
+ /* Call _exit rather than doing it inline for breakpoint purposes. */
+ move a0,v0
+#ifdef __PIC__
+ la t9,_exit
+ jalr t9
+#else
+ jal _exit
+#endif
+ END(__thread_start)
+
+weak_alias(__clone, clone)
diff --git a/libc/sysdeps/linux/mips/crt0.S b/libc/sysdeps/linux/mips/crt0.S
new file mode 100644
index 000000000..a23a012ad
--- /dev/null
+++ b/libc/sysdeps/linux/mips/crt0.S
@@ -0,0 +1,50 @@
+/* When we enter this piece of code, the program stack looks like this:
+ argc argument counter (integer)
+ argv[0] program name (pointer)
+ argv[1...N] program args (pointers)
+ argv[argc-1] end of args (integer)
+ NULL
+ env[0...N] environment variables (pointers)
+ NULL
+*/
+
+#include <features.h>
+#include "regdef.h"
+
+.text
+.global __start
+.type __start,@function
+
+__start:
+#ifdef __PIC__
+ .set noreorder
+ bltzal zero,0f
+ nop
+0: .cpload $31
+ .set reorder
+#endif
+
+ move $31, zero
+ lw a0, 0($29) /* argc */
+ addu a1, $29, 4 /* argv */
+ addu a2, a0, 1 /* load envp */
+ sll a2, a2, 2
+ add a2, a2, a1
+ /* Ok, now run uClibc's main() -- shouldn't return */
+ jal __uClibc_main
+ hlt: b hlt /* Crash if somehow it does return. */
+
+#if 0 /* this should be provided by crtbegin/crtend in the compiler */
+/* a little bit of stuff to support C++ */
+ .section .ctors,"aw"
+ .align 4
+ .global __CTOR_LIST__
+__CTOR_LIST__:
+ .long -1
+
+ .section .dtors,"aw"
+ .align 4
+ .global __DTOR_LIST__
+__DTOR_LIST__:
+ .long -1
+#endif
diff --git a/libc/sysdeps/linux/mips/crt0.c b/libc/sysdeps/linux/mips/crt0.c
deleted file mode 100644
index 90a8f82b1..000000000
--- a/libc/sysdeps/linux/mips/crt0.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * uC-libc/sysdeps/linux/mipsel/crt0.c
- * process init code for mipsel
- *
- * Copyright (C) 2001 by Lineo, Inc.
- * Author: David A. Schleef <ds@schleef.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program 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 Library General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#if 0
-asm(
- "\t.global _start\n"
- "\t_start:\n"
-// "\tstwu 1,-32(1)\n"
-// "\tb _start2\n"
- );
-#endif
-
-/* a little bit of stuff to support C++ */
-asm(
- "\t.section .ctors,\"aw\"\n"
- "\t.align 4\n"
- "\t.global __CTOR_LIST__\n"
- "__CTOR_LIST__:\n"
- "\t.long -1\n"
- "\t.section .dtors,\"aw\"\n"
- "\t.align 4\n"
- "\t.global __DTOR_LIST__\n"
- "__DTOR_LIST__:\n"
- "\t.long -1\n"
- );
-
-void __uClibc_main(int argc,void *argv,void *envp);
-
-void __start(void)
-{
- void **p;
- int argc;
-
- p=__builtin_frame_address(2);
-
- argc=*(int *)p;
-
- __uClibc_main(argc,p+1,p+2+argc);
-}
-
diff --git a/libc/sysdeps/linux/mips/fork.S b/libc/sysdeps/linux/mips/fork.S
new file mode 100644
index 000000000..327321603
--- /dev/null
+++ b/libc/sysdeps/linux/mips/fork.S
@@ -0,0 +1,31 @@
+/* Copyright (C) 1992, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Brendan Kehoe (brendan@zen.org).
+
+ 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>
+
+SYSCALL__ (fork, 0)
+ beq v1, zero, parent /* Branch if parent. */
+ nop
+ /* We are the child. Return zero. */
+ move v0, zero
+parent:
+ ret
+ .end __fork
+
+weak_alias (__fork, fork)
diff --git a/libc/sysdeps/linux/mips/regdef.h b/libc/sysdeps/linux/mips/regdef.h
new file mode 100644
index 000000000..c4df60383
--- /dev/null
+++ b/libc/sysdeps/linux/mips/regdef.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ralf Baechle <ralf@gnu.org>.
+
+ 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 _SYS_REGDEF_H
+#define _SYS_REGDEF_H
+
+/*
+ * Symbolic register names for 32 bit ABI
+ */
+#define zero $0 /* wired zero */
+#define AT $1 /* assembler temp - uppercase because of ".set at" */
+#define v0 $2 /* return value */
+#define v1 $3
+#define a0 $4 /* argument registers */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 /* caller saved */
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16 /* callee saved */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* caller saved */
+#define t9 $25
+#define jp $25 /* PIC jump register */
+#define k0 $26 /* kernel scratch */
+#define k1 $27
+#define gp $28 /* global pointer */
+#define sp $29 /* stack pointer */
+#define fp $30 /* frame pointer */
+#define s8 $30 /* same like fp! */
+#define ra $31 /* return address */
+
+#endif /* _SYS_REGDEF_H */
diff --git a/libc/sysdeps/linux/mips/setjmp.S b/libc/sysdeps/linux/mips/setjmp.S
new file mode 100644
index 000000000..63e209b78
--- /dev/null
+++ b/libc/sysdeps/linux/mips/setjmp.S
@@ -0,0 +1,53 @@
+/* Copyright (C) 1996, 1997, 2000 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "regdef.h"
+
+/* 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. */
+#ifdef __PIC__
+ .option pic2
+#endif
+
+
+.text
+.global __sigsetjmp
+.align 2;
+.ent __sigsetjmp,0;
+.type __sigsetjmp,@function
+
+__sigsetjmp:
+#ifdef __PIC__
+ .set noreorder
+ .cpload t9
+ .set reorder
+#endif
+ move a2, sp
+#ifdef fp
+ move a3, fp
+#else
+ move a3, $fp
+#endif
+#ifdef __PIC__
+ la t9, __sigsetjmp_aux
+ jr t9
+#else
+ j __sigsetjmp_aux
+#endif
+ .end __sigsetjmp