Home | History | Annotate | Download | only in arch-mips
      1 /* Derived from: $OpenBSD: setjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2001-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 implementation for libc.
     40  */
     41 
     42 FRAMESZ= MKFSIZ(2,6)
     43 A1OFF= FRAMESZ-4*REGSZ
     44 A0OFF= FRAMESZ-3*REGSZ
     45 GPOFF= FRAMESZ-2*REGSZ
     46 RAOFF= FRAMESZ-1*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 
     60 
     61 NON_LEAF(WRAP(setjmp), FRAMESZ, ra)
     62         .mask   0x80000000, RAOFF
     63         PTR_SUBU sp, FRAMESZ                    # allocate stack frame
     64         SETUP_GP64(GPOFF, WRAP(setjmp))
     65         SAVE_GP(GPOFF)
     66         .set    reorder
     67         REG_S   ra, RAOFF(sp)                   # save state
     68         REG_S   a0, A0OFF(sp)
     69 
     70         move    a0, zero                        # get current signal mask
     71         jal     sigblock
     72 
     73         REG_L   v1, A0OFF(sp)                   # v1 = jmpbuf
     74         REG_S   v0, JB_MASK(v1)                 # save sc_mask = sigblock(0)
     75 
     76         REG_L   a0, A0OFF(sp)                   # restore jmpbuf
     77         REG_L   ra, RAOFF(sp)
     78         REG_S   ra, JB_PC(a0)                   # sc_pc = return address
     79 #if defined(__mips64)
     80         dli     v0, MAGIC_SETJMP
     81 #else
     82         li      v0, MAGIC_SETJMP
     83 #endif
     84         REG_S   v0, JB_MAGIC(a0)
     85         REG_S   s0, JB_S0(a0)
     86         REG_S   s1, JB_S1(a0)
     87         REG_S   s2, JB_S2(a0)
     88         REG_S   s3, JB_S3(a0)
     89         REG_S   s4, JB_S4(a0)
     90         REG_S   s5, JB_S5(a0)
     91         REG_S   s6, JB_S6(a0)
     92         REG_S   s7, JB_S7(a0)
     93         REG_S   s8, JB_S8(a0)
     94         REG_L   v0, GPOFF(sp)
     95         REG_S   v0, JB_GP(a0)
     96         PTR_ADDU v0, sp, FRAMESZ
     97         REG_S   v0, JB_SP(a0)
     98 
     99 #if !defined(SOFTFLOAT)
    100         /*
    101          * Would be nice if we could tell if the FP registers are currently being used.
    102          * Assume they are, and use pointer to jmp_buf in a0 to save FP registers and the
    103          * jmp_buf.fpused flag.
    104          */
    105         li      v0, 1                           # v0 = 1
    106         REG_S   v0, JB_FPUSED(a0)               # a0->jb_fpused = v0:1
    107         cfc1    v0, $31
    108 #if _MIPS_FPSET == 32
    109         FPREG64_S($f20, JB_F20, a0)
    110         FPREG64_S($f21, JB_F21, a0)
    111         FPREG64_S($f22, JB_F22, a0)
    112         FPREG64_S($f23, JB_F23, a0)
    113         FPREG64_S($f24, JB_F24, a0)
    114         FPREG64_S($f25, JB_F25, a0)
    115         FPREG64_S($f26, JB_F26, a0)
    116         FPREG64_S($f27, JB_F27, a0)
    117         FPREG64_S($f28, JB_F28, a0)
    118         FPREG64_S($f29, JB_F29, a0)
    119         FPREG64_S($f30, JB_F30, a0)
    120         FPREG64_S($f31, JB_F31, a0)
    121 #else
    122         swc1    $f20, JB_F20(a0)
    123         swc1    $f21, JB_F21(a0)
    124         swc1    $f22, JB_F22(a0)
    125         swc1    $f23, JB_F23(a0)
    126         swc1    $f24, JB_F24(a0)
    127         swc1    $f25, JB_F25(a0)
    128         swc1    $f26, JB_F26(a0)
    129         swc1    $f27, JB_F27(a0)
    130         swc1    $f28, JB_F28(a0)
    131         swc1    $f29, JB_F29(a0)
    132         swc1    $f30, JB_F30(a0)
    133         swc1    $f31, JB_F31(a0)
    134 #endif
    135         REG_S   v0, JB_FSR(a0)
    136 #endif /* !SOFTFLOAT */
    137         move    v0, zero
    138         RESTORE_GP64
    139         PTR_ADDU sp, FRAMESZ
    140         j       ra
    141 
    142 botch:
    143         jal     abort
    144         RESTORE_GP64
    145         PTR_ADDU sp, FRAMESZ
    146 END(WRAP(setjmp))
    147 
    148 
    149 LEAF(WRAP(longjmp), FRAMESZ)
    150         PTR_SUBU sp, FRAMESZ
    151         SETUP_GP64(GPOFF, WRAP(longjmp))
    152         SAVE_GP(GPOFF)
    153         .set    reorder
    154         sw      a1, A1OFF(sp)
    155         sw      a0, A0OFF(sp)
    156 
    157         lw      a0, JB_MASK(a0)
    158         jal     sigsetmask
    159 
    160         lw      a0, A0OFF(sp)
    161         lw      a1, A1OFF(sp)
    162 
    163         .set    noreorder
    164         REG_L   v0, JB_MAGIC(a0)
    165         bne     v0, MAGIC_SETJMP, botch         # jump if error
    166         REG_L   ra, JB_PC(a0)
    167         REG_L   s0, JB_S0(a0)
    168         REG_L   s1, JB_S1(a0)
    169         REG_L   s2, JB_S2(a0)
    170         REG_L   s3, JB_S3(a0)
    171         REG_L   s4, JB_S4(a0)
    172         REG_L   s5, JB_S5(a0)
    173         REG_L   s6, JB_S6(a0)
    174         REG_L   s7, JB_S7(a0)
    175         REG_L   s8, JB_S8(a0)
    176         REG_L   gp, JB_GP(a0)
    177         REG_L   sp, JB_SP(a0)
    178 
    179 #if !defined(SOFTFLOAT)
    180         REG_L   v0, JB_FSR(a0)
    181         ctc1    v0, $31
    182 #if _MIPS_FPSET == 32
    183         FPREG64_L($f20, JB_F20, a0)
    184         FPREG64_L($f21, JB_F21, a0)
    185         FPREG64_L($f22, JB_F22, a0)
    186         FPREG64_L($f23, JB_F23, a0)
    187         FPREG64_L($f24, JB_F24, a0)
    188         FPREG64_L($f25, JB_F25, a0)
    189         FPREG64_L($f26, JB_F26, a0)
    190         FPREG64_L($f27, JB_F27, a0)
    191         FPREG64_L($f28, JB_F28, a0)
    192         FPREG64_L($f29, JB_F29, a0)
    193         FPREG64_L($f30, JB_F30, a0)
    194         FPREG64_L($f31, JB_F31, a0)
    195 #else
    196         lwc1    $f20, JB_F20(a0)
    197         lwc1    $f21, JB_F21(a0)
    198         lwc1    $f22, JB_F22(a0)
    199         lwc1    $f23, JB_F23(a0)
    200         lwc1    $f24, JB_F24(a0)
    201         lwc1    $f25, JB_F25(a0)
    202         lwc1    $f26, JB_F26(a0)
    203         lwc1    $f27, JB_F27(a0)
    204         lwc1    $f28, JB_F28(a0)
    205         lwc1    $f29, JB_F29(a0)
    206         lwc1    $f30, JB_F30(a0)
    207         lwc1    $f31, JB_F31(a0)
    208 #endif
    209 #endif /* !SOFTFLOAT */
    210         bne     a1, zero, 1f
    211          nop
    212         li      a1, 1                   # never return 0!
    213 1:
    214         j       ra
    215          move   v0, a1
    216 
    217 END(WRAP(longjmp))
    218