Browse Source

mips64 patch from Atsushi Nemoto:
The mips64 N32/N64 ABI have a bit different register usage convention.
Also the register size for these ABI is 8 byte. Use ld/sd for them.

Eric Andersen 18 years ago
parent
commit
cb12600bc5

+ 42 - 0
libc/sysdeps/linux/mips/__longjmp.c

@@ -20,6 +20,7 @@
 #include <features.h>
 #include <features.h>
 #include <setjmp.h>
 #include <setjmp.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <sgidefs.h>
 
 
 #ifndef	__GNUC__
 #ifndef	__GNUC__
   #error This file uses GNU C extensions; you must compile with GCC.
   #error This file uses GNU C extensions; you must compile with GCC.
@@ -38,12 +39,23 @@ void __longjmp (__jmp_buf env, int val_arg)
 
 
     /* Pull back the floating point callee-saved registers.  */
     /* Pull back the floating point callee-saved registers.  */
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+    __asm__ __volatile__ ("l.d $f24, %0" : : "m" (env[0].__fpregs[0]));
+    __asm__ __volatile__ ("l.d $f25, %0" : : "m" (env[0].__fpregs[1]));
+    __asm__ __volatile__ ("l.d $f26, %0" : : "m" (env[0].__fpregs[2]));
+    __asm__ __volatile__ ("l.d $f27, %0" : : "m" (env[0].__fpregs[3]));
+    __asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
+    __asm__ __volatile__ ("l.d $f29, %0" : : "m" (env[0].__fpregs[5]));
+    __asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[6]));
+    __asm__ __volatile__ ("l.d $f31, %0" : : "m" (env[0].__fpregs[7]));
+#else /* O32 || N32 */
     __asm__ __volatile__ ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
     __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 $f22, %0" : : "m" (env[0].__fpregs[1]));
     __asm__ __volatile__ ("l.d $f24, %0" : : "m" (env[0].__fpregs[2]));
     __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 $f26, %0" : : "m" (env[0].__fpregs[3]));
     __asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
     __asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
     __asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
     __asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
+#endif /* O32 || N32 */
 
 
     /* Get and reconstruct the floating point csr.  */
     /* Get and reconstruct the floating point csr.  */
     __asm__ __volatile__ ("lw $2, %0" : : "m" (env[0].__fpc_csr));
     __asm__ __volatile__ ("lw $2, %0" : : "m" (env[0].__fpc_csr));
@@ -51,9 +63,14 @@ void __longjmp (__jmp_buf env, int val_arg)
 #endif
 #endif
 
 
     /* Get the GP. */
     /* Get the GP. */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+    __asm__ __volatile__ ("ld $gp, %0" : : "m" (env[0].__gp));
+#else /* O32 || N32 */
     __asm__ __volatile__ ("lw $gp, %0" : : "m" (env[0].__gp));
     __asm__ __volatile__ ("lw $gp, %0" : : "m" (env[0].__gp));
+#endif /* O32 || N32 */
 
 
     /* Get the callee-saved registers.  */
     /* Get the callee-saved registers.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     __asm__ __volatile__ ("lw $16, %0" : : "m" (env[0].__regs[0]));
     __asm__ __volatile__ ("lw $16, %0" : : "m" (env[0].__regs[0]));
     __asm__ __volatile__ ("lw $17, %0" : : "m" (env[0].__regs[1]));
     __asm__ __volatile__ ("lw $17, %0" : : "m" (env[0].__regs[1]));
     __asm__ __volatile__ ("lw $18, %0" : : "m" (env[0].__regs[2]));
     __asm__ __volatile__ ("lw $18, %0" : : "m" (env[0].__regs[2]));
@@ -62,15 +79,36 @@ void __longjmp (__jmp_buf env, int val_arg)
     __asm__ __volatile__ ("lw $21, %0" : : "m" (env[0].__regs[5]));
     __asm__ __volatile__ ("lw $21, %0" : : "m" (env[0].__regs[5]));
     __asm__ __volatile__ ("lw $22, %0" : : "m" (env[0].__regs[6]));
     __asm__ __volatile__ ("lw $22, %0" : : "m" (env[0].__regs[6]));
     __asm__ __volatile__ ("lw $23, %0" : : "m" (env[0].__regs[7]));
     __asm__ __volatile__ ("lw $23, %0" : : "m" (env[0].__regs[7]));
+#else /* N32 || N64 */
+    __asm__ __volatile__ ("ld $16, %0" : : "m" (env[0].__regs[0]));
+    __asm__ __volatile__ ("ld $17, %0" : : "m" (env[0].__regs[1]));
+    __asm__ __volatile__ ("ld $18, %0" : : "m" (env[0].__regs[2]));
+    __asm__ __volatile__ ("ld $19, %0" : : "m" (env[0].__regs[3]));
+    __asm__ __volatile__ ("ld $20, %0" : : "m" (env[0].__regs[4]));
+    __asm__ __volatile__ ("ld $21, %0" : : "m" (env[0].__regs[5]));
+    __asm__ __volatile__ ("ld $22, %0" : : "m" (env[0].__regs[6]));
+    __asm__ __volatile__ ("ld $23, %0" : : "m" (env[0].__regs[7]));
+#endif /* N32 || N64 */
 
 
     /* Get the PC.  */
     /* Get the PC.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     __asm__ __volatile__ ("lw $25, %0" : : "m" (env[0].__pc));
     __asm__ __volatile__ ("lw $25, %0" : : "m" (env[0].__pc));
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+    __asm__ __volatile__ ("lw $31, %0" : : "m" (env[0].__pc));
+#else /* N64 */
+    __asm__ __volatile__ ("ld $31, %0" : : "m" (env[0].__pc));
+#endif /* N64 */
 
 
     /* Restore the stack pointer and the FP.  They have to be restored
     /* 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
        last and in a single asm as gcc, depending on options used, may
        use either of them to access env.  */
        use either of them to access env.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+    __asm__ __volatile__ ("ld $29, %0\n\t"
+	    "ld $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
+#else /* O32 || N32 */
     __asm__ __volatile__ ("lw $29, %0\n\t"
     __asm__ __volatile__ ("lw $29, %0\n\t"
 	    "lw $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
 	    "lw $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
+#endif /* O32 || N32 */
 
 
     /* Give setjmp 1 if given a 0, or what they gave us if non-zero.  */
     /* Give setjmp 1 if given a 0, or what they gave us if non-zero.  */
     if (val == 0)
     if (val == 0)
@@ -78,7 +116,11 @@ void __longjmp (__jmp_buf env, int val_arg)
     else
     else
 	__asm__ __volatile__ ("move $2, %0" : : "r" (val));
 	__asm__ __volatile__ ("move $2, %0" : : "r" (val));
 
 
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     __asm__ __volatile__ ("jr $25");
     __asm__ __volatile__ ("jr $25");
+#else /* N32 || N64 */
+    __asm__ __volatile__ ("jr $31");
+#endif /* N32 || N64 */
 
 
     /* Avoid `volatile function does return' warnings.  */
     /* Avoid `volatile function does return' warnings.  */
     for (;;);
     for (;;);

+ 10 - 0
libc/sysdeps/linux/mips/bits/setjmp.h

@@ -24,6 +24,8 @@
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 #endif
 
 
+#include <sgidefs.h>
+
 typedef struct
 typedef struct
   {
   {
     /* Program counter.  */
     /* Program counter.  */
@@ -33,7 +35,11 @@ typedef struct
     void * __sp;
     void * __sp;
 
 
     /* Callee-saved registers s0 through s7.  */
     /* Callee-saved registers s0 through s7.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     int __regs[8];
     int __regs[8];
+#else
+    long long __regs[8];
+#endif
 
 
     /* The frame pointer.  */
     /* The frame pointer.  */
     void * __fp;
     void * __fp;
@@ -45,7 +51,11 @@ typedef struct
     int __fpc_csr;
     int __fpc_csr;
 
 
     /* Callee-saved floating point registers.  */
     /* Callee-saved floating point registers.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+    double __fpregs[8];
+#else /* N32 || O32 */
     double __fpregs[6];
     double __fpregs[6];
+#endif /* N32 || O32 */
   } __jmp_buf[1];
   } __jmp_buf[1];
 
 
 #ifdef __USE_MISC
 #ifdef __USE_MISC

+ 7 - 0
libc/sysdeps/linux/mips/bsd-_setjmp.S

@@ -22,6 +22,7 @@
    in setjmp doesn't clobber the state restored by longjmp.  */
    in setjmp doesn't clobber the state restored by longjmp.  */
 
 
 #include <sys/regdef.h>
 #include <sys/regdef.h>
+#include <sys/asm.h>
 
 
 #ifdef __PIC__
 #ifdef __PIC__
 	.option pic2
 	.option pic2
@@ -35,10 +36,16 @@
 
 
 _setjmp:
 _setjmp:
 #ifdef __PIC__
 #ifdef __PIC__
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
 	.set	noreorder
 	.set	noreorder
 	.cpload t9
 	.cpload t9
 	.set	reorder
 	.set	reorder
 	la	t9, __sigsetjmp
 	la	t9, __sigsetjmp
+#else
+	.cpsetup t9, v0, _setjmp
+	PTR_LA	t9, __sigsetjmp
+	.cpreturn
+#endif
 #endif
 #endif
 	move	a1,zero		/* Pass a second argument of zero.  */
 	move	a1,zero		/* Pass a second argument of zero.  */
 #ifdef __PIC__
 #ifdef __PIC__

+ 7 - 0
libc/sysdeps/linux/mips/bsd-setjmp.S

@@ -22,6 +22,7 @@
    in setjmp doesn't clobber the state restored by longjmp.  */
    in setjmp doesn't clobber the state restored by longjmp.  */
 
 
 #include <sys/regdef.h>
 #include <sys/regdef.h>
+#include <sys/asm.h>
 
 
 #ifdef __PIC__
 #ifdef __PIC__
 	.option pic2
 	.option pic2
@@ -36,9 +37,15 @@
 setjmp:
 setjmp:
 	.set	noreorder
 	.set	noreorder
 #ifdef __PIC__
 #ifdef __PIC__
+#if _MIPS_SIM == _MIPS_SIM_ABI32
 	.cpload t9
 	.cpload t9
 	.set	reorder
 	.set	reorder
 	la	t9, __sigsetjmp
 	la	t9, __sigsetjmp
+#else	/* N32 */
+	.cpsetup t9, v0, setjmp
+	PTR_LA	t9, __sigsetjmp
+	.cprestore
+#endif	/* N32 */
 #endif
 #endif
 	li	a1, 1		/* Pass a second argument of one.  */
 	li	a1, 1		/* Pass a second argument of one.  */
 #ifdef __PIC__
 #ifdef __PIC__

+ 9 - 1
libc/sysdeps/linux/mips/setjmp.S

@@ -17,6 +17,7 @@
    02111-1307 USA.  */
    02111-1307 USA.  */
 
 
 #include <sys/regdef.h>
 #include <sys/regdef.h>
+#include <sys/asm.h>
 
 
 /* The function __sigsetjmp_aux saves all the registers, but it can't
 /* 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
    reliably access the stack or frame pointers, so we pass them in as
@@ -35,7 +36,11 @@
 __sigsetjmp:
 __sigsetjmp:
 #ifdef __PIC__
 #ifdef __PIC__
 	.set	noreorder
 	.set	noreorder
+#if _MIPS_SIM == _MIPS_SIM_ABI32
 	.cpload	t9
 	.cpload	t9
+#else
+	.cpsetup t9, v0, __sigsetjmp
+#endif
 	.set	reorder
 	.set	reorder
 #endif
 #endif
 	move	a2, sp
 	move	a2, sp
@@ -45,7 +50,10 @@ __sigsetjmp:
 	move	a3, $fp
 	move	a3, $fp
 #endif
 #endif
 #ifdef __PIC__
 #ifdef __PIC__
-	la	t9, __sigsetjmp_aux
+	PTR_LA	t9, __sigsetjmp_aux
+#if _MIPS_SIM != _MIPS_SIM_ABI32
+	.cpreturn
+#endif
 	jr	t9
 	jr	t9
 #else
 #else
 	j	__sigsetjmp_aux
 	j	__sigsetjmp_aux

+ 36 - 0
libc/sysdeps/linux/mips/setjmp_aux.c

@@ -19,6 +19,8 @@
 
 
 #include <features.h>
 #include <features.h>
 #include <setjmp.h>
 #include <setjmp.h>
+#include <sgidefs.h>
+#include <sys/asm.h>
 
 
 /* This function is only called via the assembly language routine
 /* This function is only called via the assembly language routine
    __sigsetjmp, which arranges to pass in the stack pointer and the frame
    __sigsetjmp, which arranges to pass in the stack pointer and the frame
@@ -28,20 +30,39 @@
 extern int __sigjmp_save (sigjmp_buf, int);
 extern int __sigjmp_save (sigjmp_buf, int);
 
 
 int
 int
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+__sigsetjmp_aux (jmp_buf env, int savemask, long sp, long fp)
+#else /* O32 || N32 */
 __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
 __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
+#endif /* O32 || N32 */
 {
 {
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
   /* Store the floating point callee-saved registers...  */
   /* Store the floating point callee-saved registers...  */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+  asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
+  asm volatile ("s.d $f25, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
+  asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
+  asm volatile ("s.d $f27, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
+  asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
+  asm volatile ("s.d $f29, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+  asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[6]));
+  asm volatile ("s.d $f31, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[7]));
+#else /* O32 || N32 */
   asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
   asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
   asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
   asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
   asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
   asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
   asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
   asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
   asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
   asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
   asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
   asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#endif /* O32 || N32 */
 #endif
 #endif
 
 
   /* .. and the PC;  */
   /* .. and the PC;  */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+  asm volatile ("sd $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+#else
   asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
   asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+#endif
 
 
   /* .. and the stack pointer;  */
   /* .. and the stack pointer;  */
   env[0].__jmpbuf[0].__sp = (void *) sp;
   env[0].__jmpbuf[0].__sp = (void *) sp;
@@ -50,9 +71,14 @@ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
   env[0].__jmpbuf[0].__fp = (void *) fp;
   env[0].__jmpbuf[0].__fp = (void *) fp;
 
 
   /* .. and the GP; */
   /* .. and the GP; */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+  asm volatile ("sd $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+#else
   asm volatile ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
   asm volatile ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+#endif
 
 
   /* .. and the callee-saved registers; */
   /* .. and the callee-saved registers; */
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
   asm volatile ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
   asm volatile ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
   asm volatile ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
   asm volatile ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
   asm volatile ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
   asm volatile ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
@@ -61,6 +87,16 @@ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
   asm volatile ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
   asm volatile ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
   asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
   asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
   asm volatile ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
   asm volatile ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
+#else	/* N32 || N64 */
+  asm volatile ("sd $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
+  asm volatile ("sd $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
+  asm volatile ("sd $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
+  asm volatile ("sd $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3]));
+  asm volatile ("sd $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4]));
+  asm volatile ("sd $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
+  asm volatile ("sd $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
+  asm volatile ("sd $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
+#endif	/* N32 || N64 */
 
 
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
   /* .. and finally get and reconstruct the floating point csr.  */
   /* .. and finally get and reconstruct the floating point csr.  */