Home | History | Annotate | Download | only in arch-mips
      1 /* Derived from: $OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. Neither the name of Opsycon AB nor the names of its contributors
     15  *    may be used to endorse or promote products derived from this software
     16  *    without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  *
     30  */
     31 
     32 #include <asm-generic/portability.h>
     33 #include <machine/asm.h>
     34 #include <machine/regnum.h>
     35 
     36 #include "jboffsets.h"
     37 
     38 /*
     39  * _setjmp, _longjmp (not restoring signal state)
     40  *
     41  * XXX FPSET should probably be taken from SR setting. hmmm...
     42  *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
     43  *
     44  */
     45 
     46 FRAMESZ= MKFSIZ(0,4)
     47 GPOFF= FRAMESZ-2*REGSZ
     48 
     49 #define FPREG64_S(FPR, OFF, BASE)       \
     50         swc1    FPR, OFF(BASE)  ;       \
     51         mfhc1   t0, FPR         ;       \
     52         sw      t0, OFF+4(BASE) ;
     53 
     54 #define FPREG64_L(FPR, OFF, BASE)       \
     55         lw      t0, OFF+4(BASE) ;       \
     56         lw      t1, OFF(BASE)   ;       \
     57         mtc1    t1, FPR         ;       \
     58         mthc1   t0, FPR         ;       \
     59 
     60 LEAF(_setjmp_portable, FRAMESZ)
     61         PTR_SUBU sp, FRAMESZ
     62         SETUP_GP64(GPOFF, _setjmp)
     63         SAVE_GP(GPOFF)
     64         .set    noreorder
     65 #if defined(__mips64)
     66         dli     v0, MAGIC__SETJMP
     67 #else
     68         li      v0, MAGIC__SETJMP
     69 #endif
     70         REG_S   v0, JB_MAGIC(a0)
     71         REG_S   s0, JB_S0(a0)
     72         REG_S   s1, JB_S1(a0)
     73         REG_S   s2, JB_S2(a0)
     74         REG_S   s3, JB_S3(a0)
     75         REG_S   s4, JB_S4(a0)
     76         REG_S   s5, JB_S5(a0)
     77         REG_S   s6, JB_S6(a0)
     78         REG_S   s7, JB_S7(a0)
     79         REG_S   s8, JB_S8(a0)
     80         REG_L   v0, GPOFF(sp)
     81         REG_S   v0, JB_GP(a0)
     82         PTR_ADDU v0, sp, FRAMESZ
     83         REG_S   v0, JB_SP(a0)
     84         REG_S   ra, JB_PC(a0)
     85 
     86 #if !defined(SOFTFLOAT)
     87         /*
     88          * Would be nice if we could tell if the FP registers are currently being used;
     89          * Assume they are, and use pointer to jmp_buf in a0 to save FP registers and the
     90          * jmp_buf.fpused flag.
     91          */
     92         li      v0, 1                           # v0 = 1
     93         REG_S   v0, JB_FPUSED(a0)               # a0->jb_fpused = v0:1
     94         cfc1    v0, $31
     95 #if _MIPS_FPSET == 32
     96         FPREG64_S($f20, JB_F20, a0)
     97         FPREG64_S($f21, JB_F21, a0)
     98         FPREG64_S($f22, JB_F22, a0)
     99         FPREG64_S($f23, JB_F23, a0)
    100         FPREG64_S($f24, JB_F24, a0)
    101         FPREG64_S($f25, JB_F25, a0)
    102         FPREG64_S($f26, JB_F26, a0)
    103         FPREG64_S($f27, JB_F27, a0)
    104         FPREG64_S($f28, JB_F28, a0)
    105         FPREG64_S($f29, JB_F29, a0)
    106         FPREG64_S($f30, JB_F30, a0)
    107         FPREG64_S($f31, JB_F31, a0)
    108 #else
    109         swc1    $f20, JB_F20(a0)
    110         swc1    $f21, JB_F21(a0)
    111         swc1    $f22, JB_F22(a0)
    112         swc1    $f23, JB_F23(a0)
    113         swc1    $f24, JB_F24(a0)
    114         swc1    $f25, JB_F25(a0)
    115         swc1    $f26, JB_F26(a0)
    116         swc1    $f27, JB_F27(a0)
    117         swc1    $f28, JB_F28(a0)
    118         swc1    $f29, JB_F29(a0)
    119         swc1    $f30, JB_F30(a0)
    120         swc1    $f31, JB_F31(a0)
    121 #endif
    122         REG_S   v0, JB_FSR(a0)
    123 #endif /* !SOFTFLOAT */
    124         RESTORE_GP64
    125         PTR_ADDU sp, FRAMESZ
    126         j       ra
    127          move   v0, zero
    128 END(_setjmp_portable)
    129 
    130 LEAF(_longjmp_portable, FRAMESZ)
    131         PTR_SUBU sp, FRAMESZ
    132         SETUP_GP64(GPOFF, _longjmp)
    133         SAVE_GP(GPOFF)
    134         .set    noreorder
    135         REG_L   v0, JB_MAGIC(a0)
    136         bne     v0, MAGIC__SETJMP, botch                # jump if error
    137         REG_L   ra, JB_PC(a0)
    138         REG_L   v0, JB_FSR(a0)
    139         REG_L   s0, JB_S0(a0)
    140         REG_L   s1, JB_S1(a0)
    141         REG_L   s2, JB_S2(a0)
    142         REG_L   s3, JB_S3(a0)
    143         REG_L   s4, JB_S4(a0)
    144         REG_L   s5, JB_S5(a0)
    145         REG_L   s6, JB_S6(a0)
    146         REG_L   s7, JB_S7(a0)
    147         REG_L   s8, JB_S8(a0)
    148         REG_L   gp, JB_GP(a0)
    149         REG_L   sp, JB_SP(a0)
    150 #if !defined(SOFTFLOAT)
    151         ctc1    v0, $31
    152 #if _MIPS_FPSET == 32
    153         FPREG64_L($f20, JB_F20, a0)
    154         FPREG64_L($f21, JB_F21, a0)
    155         FPREG64_L($f22, JB_F22, a0)
    156         FPREG64_L($f23, JB_F23, a0)
    157         FPREG64_L($f24, JB_F24, a0)
    158         FPREG64_L($f25, JB_F25, a0)
    159         FPREG64_L($f26, JB_F26, a0)
    160         FPREG64_L($f27, JB_F27, a0)
    161         FPREG64_L($f28, JB_F28, a0)
    162         FPREG64_L($f29, JB_F29, a0)
    163         FPREG64_L($f30, JB_F30, a0)
    164         FPREG64_L($f31, JB_F31, a0)
    165 #else
    166         lwc1    $f20, JB_F20(a0)
    167         lwc1    $f21, JB_F21(a0)
    168         lwc1    $f22, JB_F22(a0)
    169         lwc1    $f23, JB_F23(a0)
    170         lwc1    $f24, JB_F24(a0)
    171         lwc1    $f25, JB_F25(a0)
    172         lwc1    $f26, JB_F26(a0)
    173         lwc1    $f27, JB_F27(a0)
    174         lwc1    $f28, JB_F28(a0)
    175         lwc1    $f29, JB_F29(a0)
    176         lwc1    $f30, JB_F30(a0)
    177         lwc1    $f31, JB_F31(a0)
    178 #endif
    179 #endif /* !SOFTFLOAT */
    180         bne     a1, zero, 1f
    181          nop
    182         li      a1, 1                   # never return 0!
    183 1:
    184         j       ra
    185          move   v0, a1
    186 
    187 botch:
    188         jal     abort
    189         nop
    190         RESTORE_GP64
    191         PTR_ADDU sp, FRAMESZ
    192 END(_longjmp_portable)
    193