This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

setjmp on 32b MIPS with 64b FPRs


Hi,

Apparently setjmp.S does not support 32b MIPS with 64b float registers
- rather, the code has a path for 32b MIPS, which assumes 32b GPRs and
FPRs, and a path for 64b MIPS, which assumes 64b GPRs and FPRs.
However, there exist 32b MIPS processors where each $f register can
keep a 64b double-precision number.

The code below is based on setjmp.S and appears to work for me on 32b
MIPS with 64b FPRs. It is not an actual patch that can be applied to
setjmp.S because I'm unfamiliar with newlib and its build system and
so I don't know which #ifdefs to use to detect which MIPS we're
compiling for.

Hope this helps,
-- Yossi

#define GPR_LAYOUT              \
        GPR_OFFSET ($16, 0);        \
        GPR_OFFSET ($17, 1);        \
        GPR_OFFSET ($18, 2);        \
        GPR_OFFSET ($19, 3);        \
        GPR_OFFSET ($20, 4);        \
        GPR_OFFSET ($21, 5);        \
        GPR_OFFSET ($22, 6);        \
        GPR_OFFSET ($23, 7);        \
        GPR_OFFSET ($29, 8);        \
        GPR_OFFSET ($30, 9);        \
        GPR_OFFSET ($31, 10)

#define NUM_GPRS_SAVED 11

#define FPR_LAYOUT              \
        FPR_OFFSET ($f20, 0);        \
        FPR_OFFSET ($f21, 1);        \
        FPR_OFFSET ($f22, 2);        \
        FPR_OFFSET ($f23, 3);        \
        FPR_OFFSET ($f24, 4);        \
        FPR_OFFSET ($f25, 5);        \
        FPR_OFFSET ($f26, 6);        \
        FPR_OFFSET ($f27, 7);        \
        FPR_OFFSET ($f28, 8);        \
        FPR_OFFSET ($f29, 9);        \
        FPR_OFFSET ($f30, 10);        \
        FPR_OFFSET ($f31, 11)

#define GPOFF(INDEX) (INDEX * 4)
#define FPOFF(INDEX) (INDEX * 8 + (NUM_GPRS_SAVED+1) * 4) /* +1 for
alignment to 8 */

/* int setjmp (jmp_buf);  */
        .globl        setjmp
        .ent          setjmp
setjmp:
        .frame        $sp,0,$31

#define GPR_OFFSET(REG, INDEX) sw REG,GPOFF(INDEX)($4)
#define FPR_OFFSET(REG, INDEX) sdc1 REG,FPOFF(INDEX)($4)
        GPR_LAYOUT
        FPR_LAYOUT
#undef GPR_OFFSET
#undef FPR_OFFSET

        move          $2,$0
        j             $31

        .end          setjmp

/* volatile void longjmp (jmp_buf, int);  */
        .globl        longjmp
        .ent          longjmp
longjmp:
        .frame        $sp,0,$31

#define GPR_OFFSET(REG, INDEX) lw REG,GPOFF(INDEX)($4)
#define FPR_OFFSET(REG, INDEX) ldc1 REG,FPOFF(INDEX)($4)
        GPR_LAYOUT
        FPR_LAYOUT
#undef GPR_OFFSET
#undef FPR_OFFSET

        bne           $5,$0,1f
        li            $5,1
1:
        move          $2,$5
        j             $31

        .end longjmp


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]