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 <setjmp.h>
 #include <stdlib.h>
+#include <sgidefs.h>
 
 #ifndef	__GNUC__
   #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.  */
 #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 $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]));
+#endif /* O32 || N32 */
 
     /* Get and reconstruct the floating point csr.  */
     __asm__ __volatile__ ("lw $2, %0" : : "m" (env[0].__fpc_csr));
@@ -51,9 +63,14 @@ void __longjmp (__jmp_buf env, int val_arg)
 #endif
 
     /* 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));
+#endif /* O32 || N32 */
 
     /* Get the callee-saved registers.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     __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]));
@@ -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 $22, %0" : : "m" (env[0].__regs[6]));
     __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.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     __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
        last and in a single asm as gcc, depending on options used, may
        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"
 	    "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.  */
     if (val == 0)
@@ -78,7 +116,11 @@ void __longjmp (__jmp_buf env, int val_arg)
     else
 	__asm__ __volatile__ ("move $2, %0" : : "r" (val));
 
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     __asm__ __volatile__ ("jr $25");
+#else /* N32 || N64 */
+    __asm__ __volatile__ ("jr $31");
+#endif /* N32 || N64 */
 
     /* Avoid `volatile function does return' warnings.  */
     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."
 #endif
 
+#include <sgidefs.h>
+
 typedef struct
   {
     /* Program counter.  */
@@ -33,7 +35,11 @@ typedef struct
     void * __sp;
 
     /* Callee-saved registers s0 through s7.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
     int __regs[8];
+#else
+    long long __regs[8];
+#endif
 
     /* The frame pointer.  */
     void * __fp;
@@ -45,7 +51,11 @@ typedef struct
     int __fpc_csr;
 
     /* Callee-saved floating point registers.  */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+    double __fpregs[8];
+#else /* N32 || O32 */
     double __fpregs[6];
+#endif /* N32 || O32 */
   } __jmp_buf[1];
 
 #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.  */
 
 #include <sys/regdef.h>
+#include <sys/asm.h>
 
 #ifdef __PIC__
 	.option pic2
@@ -35,10 +36,16 @@
 
 _setjmp:
 #ifdef __PIC__
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
 	.set	noreorder
 	.cpload t9
 	.set	reorder
 	la	t9, __sigsetjmp
+#else
+	.cpsetup t9, v0, _setjmp
+	PTR_LA	t9, __sigsetjmp
+	.cpreturn
+#endif
 #endif
 	move	a1,zero		/* Pass a second argument of zero.  */
 #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.  */
 
 #include <sys/regdef.h>
+#include <sys/asm.h>
 
 #ifdef __PIC__
 	.option pic2
@@ -36,9 +37,15 @@
 setjmp:
 	.set	noreorder
 #ifdef __PIC__
+#if _MIPS_SIM == _MIPS_SIM_ABI32
 	.cpload t9
 	.set	reorder
 	la	t9, __sigsetjmp
+#else	/* N32 */
+	.cpsetup t9, v0, setjmp
+	PTR_LA	t9, __sigsetjmp
+	.cprestore
+#endif	/* N32 */
 #endif
 	li	a1, 1		/* Pass a second argument of one.  */
 #ifdef __PIC__

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

@@ -17,6 +17,7 @@
    02111-1307 USA.  */
 
 #include <sys/regdef.h>
+#include <sys/asm.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
@@ -35,7 +36,11 @@
 __sigsetjmp:
 #ifdef __PIC__
 	.set	noreorder
+#if _MIPS_SIM == _MIPS_SIM_ABI32
 	.cpload	t9
+#else
+	.cpsetup t9, v0, __sigsetjmp
+#endif
 	.set	reorder
 #endif
 	move	a2, sp
@@ -45,7 +50,10 @@ __sigsetjmp:
 	move	a3, $fp
 #endif
 #ifdef __PIC__
-	la	t9, __sigsetjmp_aux
+	PTR_LA	t9, __sigsetjmp_aux
+#if _MIPS_SIM != _MIPS_SIM_ABI32
+	.cpreturn
+#endif
 	jr	t9
 #else
 	j	__sigsetjmp_aux

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

@@ -19,6 +19,8 @@
 
 #include <features.h>
 #include <setjmp.h>
+#include <sgidefs.h>
+#include <sys/asm.h>
 
 /* This function is only called via the assembly language routine
    __sigsetjmp, which arranges to pass in the stack pointer and the frame
@@ -28,20 +30,39 @@
 extern int __sigjmp_save (sigjmp_buf, 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)
+#endif /* O32 || N32 */
 {
 #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
   /* 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 $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 $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 $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#endif /* O32 || N32 */
 #endif
 
   /* .. 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));
+#endif
 
   /* .. and the stack pointer;  */
   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;
 
   /* .. 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));
+#endif
 
   /* .. 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 $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
   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 $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
   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__
   /* .. and finally get and reconstruct the floating point csr.  */