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 <machine/asm.h>
     33 #include <machine/regnum.h>
     34 
     35 #include "jboffsets.h"
     36 
     37 /*
     38  * _setjmp, _longjmp (not restoring signal state)
     39  *
     40  * XXX FPSET should probably be taken from SR setting. hmmm...
     41  *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
     42  *
     43  */
     44 
     45 FRAMESZ= MKFSIZ(0,4)
     46 GPOFF= FRAMESZ-2*REGSZ
     47 
     48 #define FPREG64_S(FPR, OFF, BASE)       \
     49         swc1    FPR, OFF(BASE)  ;       \
     50         mfhc1   t0, FPR         ;       \
     51         sw      t0, OFF+4(BASE) ;
     52 
     53 #define FPREG64_L(FPR, OFF, BASE)       \
     54         lw      t0, OFF+4(BASE) ;       \
     55         lw      t1, OFF(BASE)   ;       \
     56         mtc1    t1, FPR         ;       \
     57         mthc1   t0, FPR         ;       \
     58 
     59 LEAF(_setjmp_portable, FRAMESZ)
     60         PTR_SUBU sp, FRAMESZ
     61         SETUP_GP64(GPOFF, _setjmp)
     62         SAVE_GP(GPOFF)
     63         .set    noreorder
     64 #if defined(__mips64)
     65         dli     v0, MAGIC__SETJMP
     66 #else
     67         li      v0, MAGIC__SETJMP
     68 #endif
     69         REG_S   v0, JB_MAGIC(a0)
     70         REG_S   s0, JB_S0(a0)
     71         REG_S   s1, JB_S1(a0)
     72         REG_S   s2, JB_S2(a0)
     73         REG_S   s3, JB_S3(a0)
     74         REG_S   s4, JB_S4(a0)
     75         REG_S   s5, JB_S5(a0)
     76         REG_S   s6, JB_S6(a0)
     77         REG_S   s7, JB_S7(a0)
     78         REG_S   s8, JB_S8(a0)
     79         REG_L   v0, GPOFF(sp)
     80         REG_S   v0, JB_GP(a0)
     81         PTR_ADDU v0, sp, FRAMESZ
     82         REG_S   v0, JB_SP(a0)
     83         REG_S   ra, JB_PC(a0)
     84 
     85 #if !defined(SOFTFLOAT)
     86         /*
     87          * Would be nice if we could tell if the FP registers are currently being used;
     88          * Assume they are, and use pointer to jmp_buf in a0 to save FP registers and the
     89          * jmp_buf.fpused flag.
     90          */
     91         li      v0, 1                           # v0 = 1
     92         REG_S   v0, JB_FPUSED(a0)               # a0->jb_fpused = v0:1
     93         cfc1    v0, $31
     94 #if _MIPS_FPSET == 32
     95         FPREG64_S($f20, JB_F20, a0)
     96         FPREG64_S($f21, JB_F21, a0)
     97         FPREG64_S($f22, JB_F22, a0)
     98         FPREG64_S($f23, JB_F23, a0)
     99         FPREG64_S($f24, JB_F24, a0)
    100         FPREG64_S($f25, JB_F25, a0)
    101         FPREG64_S($f26, JB_F26, a0)
    102         FPREG64_S($f27, JB_F27, a0)
    103         FPREG64_S($f28, JB_F28, a0)
    104         FPREG64_S($f29, JB_F29, a0)
    105         FPREG64_S($f30, JB_F30, a0)
    106         FPREG64_S($f31, JB_F31, a0)
    107 #else
    108         swc1    $f20, JB_F20(a0)
    109         swc1    $f21, JB_F21(a0)
    110         swc1    $f22, JB_F22(a0)
    111         swc1    $f23, JB_F23(a0)
    112         swc1    $f24, JB_F24(a0)
    113         swc1    $f25, JB_F25(a0)
    114         swc1    $f26, JB_F26(a0)
    115         swc1    $f27, JB_F27(a0)
    116         swc1    $f28, JB_F28(a0)
    117         swc1    $f29, JB_F29(a0)
    118         swc1    $f30, JB_F30(a0)
    119         swc1    $f31, JB_F31(a0)
    120 #endif
    121         REG_S   v0, JB_FSR(a0)
    122 #endif /* !SOFTFLOAT */
    123         RESTORE_GP64
    124         PTR_ADDU sp, FRAMESZ
    125         j       ra
    126          move   v0, zero
    127 END(_setjmp_portable)
    128 
    129 LEAF(_longjmp_portable, FRAMESZ)
    130         PTR_SUBU sp, FRAMESZ
    131         SETUP_GP64(GPOFF, _longjmp)
    132         SAVE_GP(GPOFF)
    133         .set    noreorder
    134         REG_L   v0, JB_MAGIC(a0)
    135         bne     v0, MAGIC__SETJMP, botch                # jump if error
    136         REG_L   ra, JB_PC(a0)
    137         REG_L   v0, JB_FSR(a0)
    138         REG_L   s0, JB_S0(a0)
    139         REG_L   s1, JB_S1(a0)
    140         REG_L   s2, JB_S2(a0)
    141         REG_L   s3, JB_S3(a0)
    142         REG_L   s4, JB_S4(a0)
    143         REG_L   s5, JB_S5(a0)
    144         REG_L   s6, JB_S6(a0)
    145         REG_L   s7, JB_S7(a0)
    146         REG_L   s8, JB_S8(a0)
    147         REG_L   gp, JB_GP(a0)
    148         REG_L   sp, JB_SP(a0)
    149 #if !defined(SOFTFLOAT)
    150         ctc1    v0, $31
    151 #if _MIPS_FPSET == 32
    152         FPREG64_L($f20, JB_F20, a0)
    153         FPREG64_L($f21, JB_F21, a0)
    154         FPREG64_L($f22, JB_F22, a0)
    155         FPREG64_L($f23, JB_F23, a0)
    156         FPREG64_L($f24, JB_F24, a0)
    157         FPREG64_L($f25, JB_F25, a0)
    158         FPREG64_L($f26, JB_F26, a0)
    159         FPREG64_L($f27, JB_F27, a0)
    160         FPREG64_L($f28, JB_F28, a0)
    161         FPREG64_L($f29, JB_F29, a0)
    162         FPREG64_L($f30, JB_F30, a0)
    163         FPREG64_L($f31, JB_F31, a0)
    164 #else
    165         lwc1    $f20, JB_F20(a0)
    166         lwc1    $f21, JB_F21(a0)
    167         lwc1    $f22, JB_F22(a0)
    168         lwc1    $f23, JB_F23(a0)
    169         lwc1    $f24, JB_F24(a0)
    170         lwc1    $f25, JB_F25(a0)
    171         lwc1    $f26, JB_F26(a0)
    172         lwc1    $f27, JB_F27(a0)
    173         lwc1    $f28, JB_F28(a0)
    174         lwc1    $f29, JB_F29(a0)
    175         lwc1    $f30, JB_F30(a0)
    176         lwc1    $f31, JB_F31(a0)
    177 #endif
    178 #endif /* !SOFTFLOAT */
    179         bne     a1, zero, 1f
    180          nop
    181         li      a1, 1                   # never return 0!
    182 1:
    183         j       ra
    184          move   v0, a1
    185 
    186 botch:
    187         jal     longjmperror
    188         nop
    189         jal     abort
    190         nop
    191         RESTORE_GP64
    192         PTR_ADDU sp, FRAMESZ
    193 END(_longjmp_portable)
    194