From: Duane Sand Date: Wed, 26 Nov 2014 01:33:10 +0000 (-0800) Subject: [MIPS] Rewrite of setjmp/longjmp for mips64 and mipsr6 X-Git-Tag: android-x86-7.1-r1~757^2~108^2~209^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=3a4786348e657fbabdd7f762439d815ea23f9dcd;p=android-x86%2Fbionic.git [MIPS] Rewrite of setjmp/longjmp for mips64 and mipsr6 Change-Id: Idcd13413520dd503bc9cf782553675313e500a83 --- diff --git a/libc/arch-mips/bionic/_setjmp.S b/libc/arch-mips/bionic/_setjmp.S index d237e6d19..052dacb4d 100644 --- a/libc/arch-mips/bionic/_setjmp.S +++ b/libc/arch-mips/bionic/_setjmp.S @@ -30,13 +30,11 @@ */ #include -#include #include /* * _setjmp, _longjmp (not restoring signal state) * - * XXX FPSET should probably be taken from SR setting. hmmm... * GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp! * */ @@ -48,103 +46,127 @@ LEAF(_setjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, _setjmp) SAVE_GP(GPOFF) - .set noreorder -#if defined(__mips64) - dli v0, 0xACEDBADE # sigcontext magic number -#else - li v0, 0xACEDBADE # sigcontext magic number + .set reorder + +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 #endif - REG_S v0, SC_REGS+ZERO*REGSZ(a0) - REG_S s0, SC_REGS+S0*REGSZ(a0) - REG_S s1, SC_REGS+S1*REGSZ(a0) - REG_S s2, SC_REGS+S2*REGSZ(a0) - REG_S s3, SC_REGS+S3*REGSZ(a0) - REG_S s4, SC_REGS+S4*REGSZ(a0) - REG_S s5, SC_REGS+S5*REGSZ(a0) - REG_S s6, SC_REGS+S6*REGSZ(a0) - REG_S s7, SC_REGS+S7*REGSZ(a0) - REG_S s8, SC_REGS+S8*REGSZ(a0) + + # SC_MASK is unused here + + li v0, 0xACEDBADE # sigcontext magic number + sw v0, SC_MAGIC(a0) + # callee-saved long-sized regs: + REG_S ra, SC_REGS+0*REGSZ(a0) + REG_S s0, SC_REGS+1*REGSZ(a0) + REG_S s1, SC_REGS+2*REGSZ(a0) + REG_S s2, SC_REGS+3*REGSZ(a0) + REG_S s3, SC_REGS+4*REGSZ(a0) + REG_S s4, SC_REGS+5*REGSZ(a0) + REG_S s5, SC_REGS+6*REGSZ(a0) + REG_S s6, SC_REGS+7*REGSZ(a0) + REG_S s7, SC_REGS+8*REGSZ(a0) + REG_S s8, SC_REGS+9*REGSZ(a0) REG_L v0, GPOFF(sp) - REG_S v0, SC_REGS+GP*REGSZ(a0) + REG_S v0, SC_REGS+10*REGSZ(a0) PTR_ADDU v0, sp, FRAMESZ - REG_S v0, SC_REGS+SP*REGSZ(a0) - REG_S ra, SC_PC(a0) + REG_S v0, SC_REGS+11*REGSZ(a0) -#if !defined(SOFTFLOAT) - li v0, 1 # be nice if we could tell - REG_S v0, SC_FPUSED(a0) # sc_fpused = 1 cfc1 v0, $31 - s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) + +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + s.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + s.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + s.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif - REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) -#endif /* !SOFTFLOAT */ + sw v0, SC_FPSR(a0) + move v0, zero RESTORE_GP64 PTR_ADDU sp, FRAMESZ j ra - move v0, zero END(_setjmp) + LEAF(_longjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, _longjmp) SAVE_GP(GPOFF) - .set noreorder - REG_L v0, SC_REGS+ZERO*REGSZ(a0) - bne v0, 0xACEDBADE, botch # jump if error - REG_L ra, SC_PC(a0) - REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) - REG_L s0, SC_REGS+S0*REGSZ(a0) - REG_L s1, SC_REGS+S1*REGSZ(a0) - REG_L s2, SC_REGS+S2*REGSZ(a0) - REG_L s3, SC_REGS+S3*REGSZ(a0) - REG_L s4, SC_REGS+S4*REGSZ(a0) - REG_L s5, SC_REGS+S5*REGSZ(a0) - REG_L s6, SC_REGS+S6*REGSZ(a0) - REG_L s7, SC_REGS+S7*REGSZ(a0) - REG_L s8, SC_REGS+S8*REGSZ(a0) - REG_L gp, SC_REGS+GP*REGSZ(a0) - REG_L sp, SC_REGS+SP*REGSZ(a0) -#if !defined(SOFTFLOAT) + .set reorder + +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 +#endif + + # SC_MASK is unused here + + lw v0, SC_MAGIC(a0) + li t0, 0xACEDBADE + bne v0, t0, botch # jump if error + + # callee-saved long-sized regs: + REG_L ra, SC_REGS+0*REGSZ(a0) + REG_L s0, SC_REGS+1*REGSZ(a0) + REG_L s1, SC_REGS+2*REGSZ(a0) + REG_L s2, SC_REGS+3*REGSZ(a0) + REG_L s3, SC_REGS+4*REGSZ(a0) + REG_L s4, SC_REGS+5*REGSZ(a0) + REG_L s5, SC_REGS+6*REGSZ(a0) + REG_L s6, SC_REGS+7*REGSZ(a0) + REG_L s7, SC_REGS+8*REGSZ(a0) + REG_L s8, SC_REGS+9*REGSZ(a0) + REG_L gp, SC_REGS+10*REGSZ(a0) + REG_L sp, SC_REGS+11*REGSZ(a0) + + lw v0, SC_FPSR(a0) ctc1 v0, $31 - l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + l.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + l.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + l.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif -#endif /* !SOFTFLOAT */ bne a1, zero, 1f - nop li a1, 1 # never return 0! 1: + move v0, a1 j ra - move v0, a1 botch: jal longjmperror - nop jal abort - nop RESTORE_GP64 PTR_ADDU sp, FRAMESZ END(_longjmp) diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S index 31786be50..a1d469552 100644 --- a/libc/arch-mips/bionic/setjmp.S +++ b/libc/arch-mips/bionic/setjmp.S @@ -30,12 +30,12 @@ */ #include -#include #include /* - * setjmp, longjmp implementation for libc. this code depends - * on the layout of the struct sigcontext in machine/signal.h. + * _setjmp, _longjmp (restoring signal state) + * + * GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp! * */ @@ -51,124 +51,139 @@ NON_LEAF(setjmp, FRAMESZ, ra) SETUP_GP64(GPOFF, setjmp) SAVE_GP(GPOFF) .set reorder + +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 +#endif + REG_S ra, RAOFF(sp) # save state REG_S a0, A0OFF(sp) - move a0, zero # get current signal mask jal sigblock + REG_L a0, A0OFF(sp) + REG_L ra, RAOFF(sp) - REG_L v1, A0OFF(sp) # v1 = jmpbuf - REG_S v0, SC_MASK(v1) # save sc_mask = sigblock(0) + REG_S v0, SC_MASK(a0) # save sc_mask = sigblock(0) - REG_L a0, A0OFF(sp) # restore jmpbuf - REG_L ra, RAOFF(sp) - REG_S ra, SC_PC(a0) # sc_pc = return address -#if defined(__mips64) - dli v0, 0xACEDBADE # sigcontext magic number -#else li v0, 0xACEDBADE # sigcontext magic number -#endif - REG_S v0, SC_REGS+ZERO*REGSZ(a0) - REG_S s0, SC_REGS+S0*REGSZ(a0) - REG_S s1, SC_REGS+S1*REGSZ(a0) - REG_S s2, SC_REGS+S2*REGSZ(a0) - REG_S s3, SC_REGS+S3*REGSZ(a0) - REG_S s4, SC_REGS+S4*REGSZ(a0) - REG_S s5, SC_REGS+S5*REGSZ(a0) - REG_S s6, SC_REGS+S6*REGSZ(a0) - REG_S s7, SC_REGS+S7*REGSZ(a0) - REG_S s8, SC_REGS+S8*REGSZ(a0) + sw v0, SC_MAGIC(a0) + # callee-saved long-sized regs: + REG_S ra, SC_REGS+0*REGSZ(a0) + REG_S s0, SC_REGS+1*REGSZ(a0) + REG_S s1, SC_REGS+2*REGSZ(a0) + REG_S s2, SC_REGS+3*REGSZ(a0) + REG_S s3, SC_REGS+4*REGSZ(a0) + REG_S s4, SC_REGS+5*REGSZ(a0) + REG_S s5, SC_REGS+6*REGSZ(a0) + REG_S s6, SC_REGS+7*REGSZ(a0) + REG_S s7, SC_REGS+8*REGSZ(a0) + REG_S s8, SC_REGS+9*REGSZ(a0) REG_L v0, GPOFF(sp) - REG_S v0, SC_REGS+GP*REGSZ(a0) + REG_S v0, SC_REGS+10*REGSZ(a0) PTR_ADDU v0, sp, FRAMESZ - REG_S v0, SC_REGS+SP*REGSZ(a0) + REG_S v0, SC_REGS+11*REGSZ(a0) -#if !defined(SOFTFLOAT) - li v0, 1 # be nice if we could tell - REG_S v0, SC_FPUSED(a0) # sc_fpused = 1 cfc1 v0, $31 - s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) + +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + s.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + s.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + s.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif - REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) -#endif /* !SOFTFLOAT */ + sw v0, SC_FPSR(a0) move v0, zero RESTORE_GP64 PTR_ADDU sp, FRAMESZ j ra - -botch: - jal longjmperror - jal abort - RESTORE_GP64 - PTR_ADDU sp, FRAMESZ END(setjmp) -LEAF(longjmp, FRAMESZ) +NON_LEAF(longjmp, FRAMESZ, ra) + .mask 0x80000000, RAOFF PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, longjmp) SAVE_GP(GPOFF) .set reorder - sw a1, A1OFF(sp) - sw a0, A0OFF(sp) +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 +#endif + + REG_S a1, A1OFF(sp) + REG_S a0, A0OFF(sp) lw a0, SC_MASK(a0) jal sigsetmask - - lw a0, A0OFF(sp) - lw a1, A1OFF(sp) - - .set noreorder - REG_L v0, SC_REGS+ZERO*REGSZ(a0) - bne v0, 0xACEDBADE, botch # jump if error - REG_L ra, SC_PC(a0) - REG_L s0, SC_REGS+S0*REGSZ(a0) - REG_L s1, SC_REGS+S1*REGSZ(a0) - REG_L s2, SC_REGS+S2*REGSZ(a0) - REG_L s3, SC_REGS+S3*REGSZ(a0) - REG_L s4, SC_REGS+S4*REGSZ(a0) - REG_L s5, SC_REGS+S5*REGSZ(a0) - REG_L s6, SC_REGS+S6*REGSZ(a0) - REG_L s7, SC_REGS+S7*REGSZ(a0) - REG_L s8, SC_REGS+S8*REGSZ(a0) - REG_L gp, SC_REGS+GP*REGSZ(a0) - REG_L sp, SC_REGS+SP*REGSZ(a0) - -#if !defined(SOFTFLOAT) - REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) + REG_L a0, A0OFF(sp) + REG_L a1, A1OFF(sp) + + lw v0, SC_MAGIC(a0) + li t0, 0xACEDBADE + bne v0, t0, botch # jump if error + + # callee-saved long-sized regs: + REG_L ra, SC_REGS+0*REGSZ(a0) + REG_L s0, SC_REGS+1*REGSZ(a0) + REG_L s1, SC_REGS+2*REGSZ(a0) + REG_L s2, SC_REGS+3*REGSZ(a0) + REG_L s3, SC_REGS+4*REGSZ(a0) + REG_L s4, SC_REGS+5*REGSZ(a0) + REG_L s5, SC_REGS+6*REGSZ(a0) + REG_L s6, SC_REGS+7*REGSZ(a0) + REG_L s7, SC_REGS+8*REGSZ(a0) + REG_L s8, SC_REGS+9*REGSZ(a0) + REG_L gp, SC_REGS+10*REGSZ(a0) + REG_L sp, SC_REGS+11*REGSZ(a0) + + lw v0, SC_FPSR(a0) ctc1 v0, $31 - l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + l.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + l.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + l.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif -#endif /* !SOFTFLOAT */ bne a1, zero, 1f - nop li a1, 1 # never return 0! 1: + move v0, a1 j ra - move v0, a1 +botch: + jal longjmperror + jal abort + RESTORE_GP64 + PTR_ADDU sp, FRAMESZ END(longjmp) diff --git a/libc/arch-mips/bionic/sigsetjmp.S b/libc/arch-mips/bionic/sigsetjmp.S index 9d2e5ea87..3ef0a6fdd 100644 --- a/libc/arch-mips/bionic/sigsetjmp.S +++ b/libc/arch-mips/bionic/sigsetjmp.S @@ -32,7 +32,6 @@ */ #include -#include #include /* @@ -46,7 +45,7 @@ LEAF(sigsetjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, sigsetjmp) .set reorder - REG_S a1, (_JBLEN*REGSZ)(a0) # save "savemask" + sw a1, _JBLEN*REGSZ(a0) # save "savemask" bne a1, 0x0, 1f # do saving of signal mask? LA t9, _setjmp RESTORE_GP64 @@ -63,7 +62,7 @@ LEAF(siglongjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, siglongjmp) .set reorder - REG_L t0, (_JBLEN*REGSZ)(a0) # get "savemask" + lw t0, _JBLEN*REGSZ(a0) # get "savemask" bne t0, 0x0, 1f # restore signal mask? LA t9, _longjmp RESTORE_GP64 diff --git a/libc/arch-mips/include/machine/regdef.h b/libc/arch-mips/include/machine/regdef.h index ae1839239..3a7cd687c 100644 --- a/libc/arch-mips/include/machine/regdef.h +++ b/libc/arch-mips/include/machine/regdef.h @@ -37,6 +37,13 @@ #ifndef _MIPS_REGDEF_H_ #define _MIPS_REGDEF_H_ +#if (_MIPS_SIM == _ABI64) && !defined(__mips_n64) +#define __mips_n64 1 +#endif +#if (_MIPS_SIM == _ABIN32) && !defined(__mips_n32) +#define __mips_n32 1 +#endif + #define zero $0 /* always zero */ #define AT $at /* assembler temp */ #define v0 $2 /* return value */ diff --git a/libc/arch-mips/include/machine/regnum.h b/libc/arch-mips/include/machine/regnum.h deleted file mode 100644 index bfe128047..000000000 --- a/libc/arch-mips/include/machine/regnum.h +++ /dev/null @@ -1,119 +0,0 @@ -/* $OpenBSD: regnum.h,v 1.3 2004/08/10 20:28:13 deraadt Exp $ */ - -/* - * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifndef _MIPS64_REGNUM_H_ -#define _MIPS64_REGNUM_H_ - -/* - * Location of the saved registers relative to ZERO. - * Usage is p->p_regs[XX]. - */ -#define ZERO 0 -#define AST 1 -#define V0 2 -#define V1 3 -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define T0 8 -#define T1 9 -#define T2 10 -#define T3 11 -#define T4 12 -#define T5 13 -#define T6 14 -#define T7 15 -#define S0 16 -#define S1 17 -#define S2 18 -#define S3 19 -#define S4 20 -#define S5 21 -#define S6 22 -#define S7 23 -#define T8 24 -#define T9 25 -#define K0 26 -#define K1 27 -#define GP 28 -#define SP 29 -#define S8 30 -#define RA 31 -#define SR 32 -#define PS SR /* alias for SR */ -#define MULLO 33 -#define MULHI 34 -#define BADVADDR 35 -#define CAUSE 36 -#define PC 37 -#define IC 38 -#define CPL 39 - -#define NUMSAVEREGS 40 /* Number of registers saved in trap */ - -#define FPBASE NUMSAVEREGS -#define F0 (FPBASE+0) -#define F1 (FPBASE+1) -#define F2 (FPBASE+2) -#define F3 (FPBASE+3) -#define F4 (FPBASE+4) -#define F5 (FPBASE+5) -#define F6 (FPBASE+6) -#define F7 (FPBASE+7) -#define F8 (FPBASE+8) -#define F9 (FPBASE+9) -#define F10 (FPBASE+10) -#define F11 (FPBASE+11) -#define F12 (FPBASE+12) -#define F13 (FPBASE+13) -#define F14 (FPBASE+14) -#define F15 (FPBASE+15) -#define F16 (FPBASE+16) -#define F17 (FPBASE+17) -#define F18 (FPBASE+18) -#define F19 (FPBASE+19) -#define F20 (FPBASE+20) -#define F21 (FPBASE+21) -#define F22 (FPBASE+22) -#define F23 (FPBASE+23) -#define F24 (FPBASE+24) -#define F25 (FPBASE+25) -#define F26 (FPBASE+26) -#define F27 (FPBASE+27) -#define F28 (FPBASE+28) -#define F29 (FPBASE+29) -#define F30 (FPBASE+30) -#define F31 (FPBASE+31) -#define FSR (FPBASE+32) - -#define NUMFPREGS 33 - -#define NREGS (NUMSAVEREGS + NUMFPREGS) - -#endif /* !_MIPS64_REGNUM_H_ */ diff --git a/libc/arch-mips/include/machine/setjmp.h b/libc/arch-mips/include/machine/setjmp.h index 55ba7bebb..a9707dc2e 100644 --- a/libc/arch-mips/include/machine/setjmp.h +++ b/libc/arch-mips/include/machine/setjmp.h @@ -5,6 +5,10 @@ #ifndef _MIPS_SETJMP_H_ #define _MIPS_SETJMP_H_ -#define _JBLEN 157 /* size, in longs, of a jmp_buf */ +#ifdef __LP64__ +#define _JBLEN 22 /* size, in 8-byte longs, of a mips64 jmp_buf */ +#else +#define _JBLEN 29 /* size, in 4-byte longs, of a mips32 jmp_buf */ +#endif #endif /* !_MIPS_SETJMP_H_ */ diff --git a/libc/arch-mips/include/machine/signal.h b/libc/arch-mips/include/machine/signal.h index b31715cce..b9c136718 100644 --- a/libc/arch-mips/include/machine/signal.h +++ b/libc/arch-mips/include/machine/signal.h @@ -37,15 +37,42 @@ #ifndef _MIPS_SIGNAL_H_ #define _MIPS_SIGNAL_H_ -#define SC_REGMASK (0*REGSZ) -#define SC_STATUS (1*REGSZ) -#define SC_PC (2*REGSZ) -#define SC_REGS (SC_PC+8) -#define SC_FPREGS (SC_REGS+32*8) -#define SC_ACX (SC_FPREGS+32*REGSZ_FP) -#define SC_USED_MATH (SC_ACX+3*REGSZ) -/* OpenBSD compatibility */ -#define SC_MASK SC_REGMASK -#define SC_FPUSED SC_USED_MATH +/* On Mips32, jmpbuf begins with optional 4-byte filler so that + * all saved FP regs are aligned on 8-byte boundary, despite this whole + * struct being mis-declared to users as an array of (4-byte) longs. + * All the following offsets are then from the rounded-up base addr + */ + +/* Fields of same size on all MIPS abis: */ +#define SC_MAGIC (0*4) /* 4 bytes, identify jmpbuf */ +#define SC_MASK (1*4) /* 4 bytes, saved signal mask */ +#define SC_FPSR (2*4) /* 4 bytes, floating point control/status reg */ +/* filler2 (3*4) 4 bytes, pad to 8-byte boundary */ + +/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */ +#define SC_REGS_SAVED 12 /* ra,gp,sp,s0-s8 */ +#define SC_REGS (4*4) /* SC_REGS_SAVED*REGSZ bytes */ + +/* Floating pt registers are 8-bytes on all abis, + * but the number of saved fp regs varies for o32/n32 versus n64 abis: + */ + +#ifdef __LP64__ +#define SC_FPREGS_SAVED 8 /* all fp regs f24,f25,f26,f27,f28,f29,f30,f31 */ +#else +#define SC_FPREGS_SAVED 6 /* even fp regs f20,f22,f24,f26,f28,f30 */ +#endif + +#define SC_FPREGS (SC_REGS + SC_REGS_SAVED*REGSZ) /* SC_FPREGS_SAVED*REGSZ_FP bytes */ + +#define SC_BYTES (SC_FPREGS + SC_FPREGS_SAVED*REGSZ_FP) +#define SC_LONGS (SC_BYTES/REGSZ) + +#ifdef __LP64__ +/* SC_LONGS is 22, so _JBLEN should be 22 or larger */ +#else +/* SC_LONGS is 28, but must also allocate dynamic-roundup filler. + so _JBLEN should be 29 or larger */ +#endif #endif /* !_MIPS_SIGNAL_H_ */ diff --git a/libc/arch-mips64/bionic/_setjmp.S b/libc/arch-mips64/bionic/_setjmp.S index d237e6d19..052dacb4d 100644 --- a/libc/arch-mips64/bionic/_setjmp.S +++ b/libc/arch-mips64/bionic/_setjmp.S @@ -30,13 +30,11 @@ */ #include -#include #include /* * _setjmp, _longjmp (not restoring signal state) * - * XXX FPSET should probably be taken from SR setting. hmmm... * GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp! * */ @@ -48,103 +46,127 @@ LEAF(_setjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, _setjmp) SAVE_GP(GPOFF) - .set noreorder -#if defined(__mips64) - dli v0, 0xACEDBADE # sigcontext magic number -#else - li v0, 0xACEDBADE # sigcontext magic number + .set reorder + +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 #endif - REG_S v0, SC_REGS+ZERO*REGSZ(a0) - REG_S s0, SC_REGS+S0*REGSZ(a0) - REG_S s1, SC_REGS+S1*REGSZ(a0) - REG_S s2, SC_REGS+S2*REGSZ(a0) - REG_S s3, SC_REGS+S3*REGSZ(a0) - REG_S s4, SC_REGS+S4*REGSZ(a0) - REG_S s5, SC_REGS+S5*REGSZ(a0) - REG_S s6, SC_REGS+S6*REGSZ(a0) - REG_S s7, SC_REGS+S7*REGSZ(a0) - REG_S s8, SC_REGS+S8*REGSZ(a0) + + # SC_MASK is unused here + + li v0, 0xACEDBADE # sigcontext magic number + sw v0, SC_MAGIC(a0) + # callee-saved long-sized regs: + REG_S ra, SC_REGS+0*REGSZ(a0) + REG_S s0, SC_REGS+1*REGSZ(a0) + REG_S s1, SC_REGS+2*REGSZ(a0) + REG_S s2, SC_REGS+3*REGSZ(a0) + REG_S s3, SC_REGS+4*REGSZ(a0) + REG_S s4, SC_REGS+5*REGSZ(a0) + REG_S s5, SC_REGS+6*REGSZ(a0) + REG_S s6, SC_REGS+7*REGSZ(a0) + REG_S s7, SC_REGS+8*REGSZ(a0) + REG_S s8, SC_REGS+9*REGSZ(a0) REG_L v0, GPOFF(sp) - REG_S v0, SC_REGS+GP*REGSZ(a0) + REG_S v0, SC_REGS+10*REGSZ(a0) PTR_ADDU v0, sp, FRAMESZ - REG_S v0, SC_REGS+SP*REGSZ(a0) - REG_S ra, SC_PC(a0) + REG_S v0, SC_REGS+11*REGSZ(a0) -#if !defined(SOFTFLOAT) - li v0, 1 # be nice if we could tell - REG_S v0, SC_FPUSED(a0) # sc_fpused = 1 cfc1 v0, $31 - s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) + +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + s.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + s.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + s.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif - REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) -#endif /* !SOFTFLOAT */ + sw v0, SC_FPSR(a0) + move v0, zero RESTORE_GP64 PTR_ADDU sp, FRAMESZ j ra - move v0, zero END(_setjmp) + LEAF(_longjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, _longjmp) SAVE_GP(GPOFF) - .set noreorder - REG_L v0, SC_REGS+ZERO*REGSZ(a0) - bne v0, 0xACEDBADE, botch # jump if error - REG_L ra, SC_PC(a0) - REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) - REG_L s0, SC_REGS+S0*REGSZ(a0) - REG_L s1, SC_REGS+S1*REGSZ(a0) - REG_L s2, SC_REGS+S2*REGSZ(a0) - REG_L s3, SC_REGS+S3*REGSZ(a0) - REG_L s4, SC_REGS+S4*REGSZ(a0) - REG_L s5, SC_REGS+S5*REGSZ(a0) - REG_L s6, SC_REGS+S6*REGSZ(a0) - REG_L s7, SC_REGS+S7*REGSZ(a0) - REG_L s8, SC_REGS+S8*REGSZ(a0) - REG_L gp, SC_REGS+GP*REGSZ(a0) - REG_L sp, SC_REGS+SP*REGSZ(a0) -#if !defined(SOFTFLOAT) + .set reorder + +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 +#endif + + # SC_MASK is unused here + + lw v0, SC_MAGIC(a0) + li t0, 0xACEDBADE + bne v0, t0, botch # jump if error + + # callee-saved long-sized regs: + REG_L ra, SC_REGS+0*REGSZ(a0) + REG_L s0, SC_REGS+1*REGSZ(a0) + REG_L s1, SC_REGS+2*REGSZ(a0) + REG_L s2, SC_REGS+3*REGSZ(a0) + REG_L s3, SC_REGS+4*REGSZ(a0) + REG_L s4, SC_REGS+5*REGSZ(a0) + REG_L s5, SC_REGS+6*REGSZ(a0) + REG_L s6, SC_REGS+7*REGSZ(a0) + REG_L s7, SC_REGS+8*REGSZ(a0) + REG_L s8, SC_REGS+9*REGSZ(a0) + REG_L gp, SC_REGS+10*REGSZ(a0) + REG_L sp, SC_REGS+11*REGSZ(a0) + + lw v0, SC_FPSR(a0) ctc1 v0, $31 - l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + l.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + l.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + l.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif -#endif /* !SOFTFLOAT */ bne a1, zero, 1f - nop li a1, 1 # never return 0! 1: + move v0, a1 j ra - move v0, a1 botch: jal longjmperror - nop jal abort - nop RESTORE_GP64 PTR_ADDU sp, FRAMESZ END(_longjmp) diff --git a/libc/arch-mips64/bionic/setjmp.S b/libc/arch-mips64/bionic/setjmp.S index 31786be50..a1d469552 100644 --- a/libc/arch-mips64/bionic/setjmp.S +++ b/libc/arch-mips64/bionic/setjmp.S @@ -30,12 +30,12 @@ */ #include -#include #include /* - * setjmp, longjmp implementation for libc. this code depends - * on the layout of the struct sigcontext in machine/signal.h. + * _setjmp, _longjmp (restoring signal state) + * + * GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp! * */ @@ -51,124 +51,139 @@ NON_LEAF(setjmp, FRAMESZ, ra) SETUP_GP64(GPOFF, setjmp) SAVE_GP(GPOFF) .set reorder + +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 +#endif + REG_S ra, RAOFF(sp) # save state REG_S a0, A0OFF(sp) - move a0, zero # get current signal mask jal sigblock + REG_L a0, A0OFF(sp) + REG_L ra, RAOFF(sp) - REG_L v1, A0OFF(sp) # v1 = jmpbuf - REG_S v0, SC_MASK(v1) # save sc_mask = sigblock(0) + REG_S v0, SC_MASK(a0) # save sc_mask = sigblock(0) - REG_L a0, A0OFF(sp) # restore jmpbuf - REG_L ra, RAOFF(sp) - REG_S ra, SC_PC(a0) # sc_pc = return address -#if defined(__mips64) - dli v0, 0xACEDBADE # sigcontext magic number -#else li v0, 0xACEDBADE # sigcontext magic number -#endif - REG_S v0, SC_REGS+ZERO*REGSZ(a0) - REG_S s0, SC_REGS+S0*REGSZ(a0) - REG_S s1, SC_REGS+S1*REGSZ(a0) - REG_S s2, SC_REGS+S2*REGSZ(a0) - REG_S s3, SC_REGS+S3*REGSZ(a0) - REG_S s4, SC_REGS+S4*REGSZ(a0) - REG_S s5, SC_REGS+S5*REGSZ(a0) - REG_S s6, SC_REGS+S6*REGSZ(a0) - REG_S s7, SC_REGS+S7*REGSZ(a0) - REG_S s8, SC_REGS+S8*REGSZ(a0) + sw v0, SC_MAGIC(a0) + # callee-saved long-sized regs: + REG_S ra, SC_REGS+0*REGSZ(a0) + REG_S s0, SC_REGS+1*REGSZ(a0) + REG_S s1, SC_REGS+2*REGSZ(a0) + REG_S s2, SC_REGS+3*REGSZ(a0) + REG_S s3, SC_REGS+4*REGSZ(a0) + REG_S s4, SC_REGS+5*REGSZ(a0) + REG_S s5, SC_REGS+6*REGSZ(a0) + REG_S s6, SC_REGS+7*REGSZ(a0) + REG_S s7, SC_REGS+8*REGSZ(a0) + REG_S s8, SC_REGS+9*REGSZ(a0) REG_L v0, GPOFF(sp) - REG_S v0, SC_REGS+GP*REGSZ(a0) + REG_S v0, SC_REGS+10*REGSZ(a0) PTR_ADDU v0, sp, FRAMESZ - REG_S v0, SC_REGS+SP*REGSZ(a0) + REG_S v0, SC_REGS+11*REGSZ(a0) -#if !defined(SOFTFLOAT) - li v0, 1 # be nice if we could tell - REG_S v0, SC_FPUSED(a0) # sc_fpused = 1 cfc1 v0, $31 - s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) + +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + s.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + s.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + s.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + s.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + s.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + s.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + s.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif - REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) -#endif /* !SOFTFLOAT */ + sw v0, SC_FPSR(a0) move v0, zero RESTORE_GP64 PTR_ADDU sp, FRAMESZ j ra - -botch: - jal longjmperror - jal abort - RESTORE_GP64 - PTR_ADDU sp, FRAMESZ END(setjmp) -LEAF(longjmp, FRAMESZ) +NON_LEAF(longjmp, FRAMESZ, ra) + .mask 0x80000000, RAOFF PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, longjmp) SAVE_GP(GPOFF) .set reorder - sw a1, A1OFF(sp) - sw a0, A0OFF(sp) +#ifndef __LP64__ + addiu a0, 7 # roundup jmpbuf addr to 8-byte boundary + li t0, ~7 + and a0, t0 +#endif + + REG_S a1, A1OFF(sp) + REG_S a0, A0OFF(sp) lw a0, SC_MASK(a0) jal sigsetmask - - lw a0, A0OFF(sp) - lw a1, A1OFF(sp) - - .set noreorder - REG_L v0, SC_REGS+ZERO*REGSZ(a0) - bne v0, 0xACEDBADE, botch # jump if error - REG_L ra, SC_PC(a0) - REG_L s0, SC_REGS+S0*REGSZ(a0) - REG_L s1, SC_REGS+S1*REGSZ(a0) - REG_L s2, SC_REGS+S2*REGSZ(a0) - REG_L s3, SC_REGS+S3*REGSZ(a0) - REG_L s4, SC_REGS+S4*REGSZ(a0) - REG_L s5, SC_REGS+S5*REGSZ(a0) - REG_L s6, SC_REGS+S6*REGSZ(a0) - REG_L s7, SC_REGS+S7*REGSZ(a0) - REG_L s8, SC_REGS+S8*REGSZ(a0) - REG_L gp, SC_REGS+GP*REGSZ(a0) - REG_L sp, SC_REGS+SP*REGSZ(a0) - -#if !defined(SOFTFLOAT) - REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) + REG_L a0, A0OFF(sp) + REG_L a1, A1OFF(sp) + + lw v0, SC_MAGIC(a0) + li t0, 0xACEDBADE + bne v0, t0, botch # jump if error + + # callee-saved long-sized regs: + REG_L ra, SC_REGS+0*REGSZ(a0) + REG_L s0, SC_REGS+1*REGSZ(a0) + REG_L s1, SC_REGS+2*REGSZ(a0) + REG_L s2, SC_REGS+3*REGSZ(a0) + REG_L s3, SC_REGS+4*REGSZ(a0) + REG_L s4, SC_REGS+5*REGSZ(a0) + REG_L s5, SC_REGS+6*REGSZ(a0) + REG_L s6, SC_REGS+7*REGSZ(a0) + REG_L s7, SC_REGS+8*REGSZ(a0) + REG_L s8, SC_REGS+9*REGSZ(a0) + REG_L gp, SC_REGS+10*REGSZ(a0) + REG_L sp, SC_REGS+11*REGSZ(a0) + + lw v0, SC_FPSR(a0) ctc1 v0, $31 - l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) - l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) - l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) - l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) - l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) - l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) -#if _MIPS_FPSET == 32 - l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) - l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) - l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) - l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) - l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) - l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) +#ifdef __LP64__ + # callee-saved fp regs on mips n64 ABI are $f24..$f31 + l.d $f24, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f25, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f27, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f29, SC_FPREGS+5*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+6*REGSZ_FP(a0) + l.d $f31, SC_FPREGS+7*REGSZ_FP(a0) +#else + # callee-saved fp regs on mips o32 ABI are + # the even-numbered fp regs $f20,$f22,...$f30 + l.d $f20, SC_FPREGS+0*REGSZ_FP(a0) + l.d $f22, SC_FPREGS+1*REGSZ_FP(a0) + l.d $f24, SC_FPREGS+2*REGSZ_FP(a0) + l.d $f26, SC_FPREGS+3*REGSZ_FP(a0) + l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) + l.d $f30, SC_FPREGS+5*REGSZ_FP(a0) #endif -#endif /* !SOFTFLOAT */ bne a1, zero, 1f - nop li a1, 1 # never return 0! 1: + move v0, a1 j ra - move v0, a1 +botch: + jal longjmperror + jal abort + RESTORE_GP64 + PTR_ADDU sp, FRAMESZ END(longjmp) diff --git a/libc/arch-mips64/bionic/sigsetjmp.S b/libc/arch-mips64/bionic/sigsetjmp.S index 9d2e5ea87..3ef0a6fdd 100644 --- a/libc/arch-mips64/bionic/sigsetjmp.S +++ b/libc/arch-mips64/bionic/sigsetjmp.S @@ -32,7 +32,6 @@ */ #include -#include #include /* @@ -46,7 +45,7 @@ LEAF(sigsetjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, sigsetjmp) .set reorder - REG_S a1, (_JBLEN*REGSZ)(a0) # save "savemask" + sw a1, _JBLEN*REGSZ(a0) # save "savemask" bne a1, 0x0, 1f # do saving of signal mask? LA t9, _setjmp RESTORE_GP64 @@ -63,7 +62,7 @@ LEAF(siglongjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, siglongjmp) .set reorder - REG_L t0, (_JBLEN*REGSZ)(a0) # get "savemask" + lw t0, _JBLEN*REGSZ(a0) # get "savemask" bne t0, 0x0, 1f # restore signal mask? LA t9, _longjmp RESTORE_GP64 diff --git a/libc/arch-mips64/include/machine/regnum.h b/libc/arch-mips64/include/machine/regnum.h deleted file mode 100644 index bfe128047..000000000 --- a/libc/arch-mips64/include/machine/regnum.h +++ /dev/null @@ -1,119 +0,0 @@ -/* $OpenBSD: regnum.h,v 1.3 2004/08/10 20:28:13 deraadt Exp $ */ - -/* - * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifndef _MIPS64_REGNUM_H_ -#define _MIPS64_REGNUM_H_ - -/* - * Location of the saved registers relative to ZERO. - * Usage is p->p_regs[XX]. - */ -#define ZERO 0 -#define AST 1 -#define V0 2 -#define V1 3 -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define T0 8 -#define T1 9 -#define T2 10 -#define T3 11 -#define T4 12 -#define T5 13 -#define T6 14 -#define T7 15 -#define S0 16 -#define S1 17 -#define S2 18 -#define S3 19 -#define S4 20 -#define S5 21 -#define S6 22 -#define S7 23 -#define T8 24 -#define T9 25 -#define K0 26 -#define K1 27 -#define GP 28 -#define SP 29 -#define S8 30 -#define RA 31 -#define SR 32 -#define PS SR /* alias for SR */ -#define MULLO 33 -#define MULHI 34 -#define BADVADDR 35 -#define CAUSE 36 -#define PC 37 -#define IC 38 -#define CPL 39 - -#define NUMSAVEREGS 40 /* Number of registers saved in trap */ - -#define FPBASE NUMSAVEREGS -#define F0 (FPBASE+0) -#define F1 (FPBASE+1) -#define F2 (FPBASE+2) -#define F3 (FPBASE+3) -#define F4 (FPBASE+4) -#define F5 (FPBASE+5) -#define F6 (FPBASE+6) -#define F7 (FPBASE+7) -#define F8 (FPBASE+8) -#define F9 (FPBASE+9) -#define F10 (FPBASE+10) -#define F11 (FPBASE+11) -#define F12 (FPBASE+12) -#define F13 (FPBASE+13) -#define F14 (FPBASE+14) -#define F15 (FPBASE+15) -#define F16 (FPBASE+16) -#define F17 (FPBASE+17) -#define F18 (FPBASE+18) -#define F19 (FPBASE+19) -#define F20 (FPBASE+20) -#define F21 (FPBASE+21) -#define F22 (FPBASE+22) -#define F23 (FPBASE+23) -#define F24 (FPBASE+24) -#define F25 (FPBASE+25) -#define F26 (FPBASE+26) -#define F27 (FPBASE+27) -#define F28 (FPBASE+28) -#define F29 (FPBASE+29) -#define F30 (FPBASE+30) -#define F31 (FPBASE+31) -#define FSR (FPBASE+32) - -#define NUMFPREGS 33 - -#define NREGS (NUMSAVEREGS + NUMFPREGS) - -#endif /* !_MIPS64_REGNUM_H_ */ diff --git a/libc/arch-mips64/include/machine/setjmp.h b/libc/arch-mips64/include/machine/setjmp.h index 55ba7bebb..a9707dc2e 100644 --- a/libc/arch-mips64/include/machine/setjmp.h +++ b/libc/arch-mips64/include/machine/setjmp.h @@ -5,6 +5,10 @@ #ifndef _MIPS_SETJMP_H_ #define _MIPS_SETJMP_H_ -#define _JBLEN 157 /* size, in longs, of a jmp_buf */ +#ifdef __LP64__ +#define _JBLEN 22 /* size, in 8-byte longs, of a mips64 jmp_buf */ +#else +#define _JBLEN 29 /* size, in 4-byte longs, of a mips32 jmp_buf */ +#endif #endif /* !_MIPS_SETJMP_H_ */ diff --git a/libc/arch-mips64/include/machine/signal.h b/libc/arch-mips64/include/machine/signal.h index b31715cce..b9c136718 100644 --- a/libc/arch-mips64/include/machine/signal.h +++ b/libc/arch-mips64/include/machine/signal.h @@ -37,15 +37,42 @@ #ifndef _MIPS_SIGNAL_H_ #define _MIPS_SIGNAL_H_ -#define SC_REGMASK (0*REGSZ) -#define SC_STATUS (1*REGSZ) -#define SC_PC (2*REGSZ) -#define SC_REGS (SC_PC+8) -#define SC_FPREGS (SC_REGS+32*8) -#define SC_ACX (SC_FPREGS+32*REGSZ_FP) -#define SC_USED_MATH (SC_ACX+3*REGSZ) -/* OpenBSD compatibility */ -#define SC_MASK SC_REGMASK -#define SC_FPUSED SC_USED_MATH +/* On Mips32, jmpbuf begins with optional 4-byte filler so that + * all saved FP regs are aligned on 8-byte boundary, despite this whole + * struct being mis-declared to users as an array of (4-byte) longs. + * All the following offsets are then from the rounded-up base addr + */ + +/* Fields of same size on all MIPS abis: */ +#define SC_MAGIC (0*4) /* 4 bytes, identify jmpbuf */ +#define SC_MASK (1*4) /* 4 bytes, saved signal mask */ +#define SC_FPSR (2*4) /* 4 bytes, floating point control/status reg */ +/* filler2 (3*4) 4 bytes, pad to 8-byte boundary */ + +/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */ +#define SC_REGS_SAVED 12 /* ra,gp,sp,s0-s8 */ +#define SC_REGS (4*4) /* SC_REGS_SAVED*REGSZ bytes */ + +/* Floating pt registers are 8-bytes on all abis, + * but the number of saved fp regs varies for o32/n32 versus n64 abis: + */ + +#ifdef __LP64__ +#define SC_FPREGS_SAVED 8 /* all fp regs f24,f25,f26,f27,f28,f29,f30,f31 */ +#else +#define SC_FPREGS_SAVED 6 /* even fp regs f20,f22,f24,f26,f28,f30 */ +#endif + +#define SC_FPREGS (SC_REGS + SC_REGS_SAVED*REGSZ) /* SC_FPREGS_SAVED*REGSZ_FP bytes */ + +#define SC_BYTES (SC_FPREGS + SC_FPREGS_SAVED*REGSZ_FP) +#define SC_LONGS (SC_BYTES/REGSZ) + +#ifdef __LP64__ +/* SC_LONGS is 22, so _JBLEN should be 22 or larger */ +#else +/* SC_LONGS is 28, but must also allocate dynamic-roundup filler. + so _JBLEN should be 29 or larger */ +#endif #endif /* !_MIPS_SIGNAL_H_ */