1 /* This is a simple version of setjmp and longjmp for MIPS 32 and 64.
3 Ian Lance Taylor, Cygnus Support, 13 May 1993. */
6 /* This file contains 32 bit assembly code. */
11 GPR_OFFSET ($16, 0); \
12 GPR_OFFSET ($17, 1); \
13 GPR_OFFSET ($18, 2); \
14 GPR_OFFSET ($19, 3); \
15 GPR_OFFSET ($20, 4); \
16 GPR_OFFSET ($21, 5); \
17 GPR_OFFSET ($22, 6); \
18 GPR_OFFSET ($23, 7); \
19 GPR_OFFSET ($29, 8); \
20 GPR_OFFSET ($30, 9); \
23 #define NUM_GPRS_SAVED 11
25 #ifdef __mips_hard_float
26 #if _MIPS_SIM == _ABIN32
28 FPR_OFFSET ($f20, 0); \
29 FPR_OFFSET ($f22, 1); \
30 FPR_OFFSET ($f24, 2); \
31 FPR_OFFSET ($f26, 3); \
32 FPR_OFFSET ($f28, 4); \
34 #elif _MIPS_SIM == _ABI64
36 FPR_OFFSET ($f24, 0); \
37 FPR_OFFSET ($f25, 1); \
38 FPR_OFFSET ($f26, 2); \
39 FPR_OFFSET ($f27, 3); \
40 FPR_OFFSET ($f28, 4); \
41 FPR_OFFSET ($f29, 5); \
42 FPR_OFFSET ($f30, 6); \
44 #elif __mips_fpr == 0 || __mips_fpr == 64
46 /* This deals with the o32 FPXX and FP64 cases. Here we must use
47 SDC1 and LDC1 to access the FPRs. These instructions require
48 8-byte aligned addresses.
49 Unfortunately, the MIPS jmp_buf only guarantees 4-byte alignment
50 and this cannot be increased without breaking compatibility with
51 pre-existing objects built against newlib. There are 11 GPRS
52 saved in the jmp_buf so a buffer that happens to be 8-byte aligned
53 ends up leaving the FPR slots 4-byte aligned and an (only) 4-byte
54 aligned buffer leads to the FPR slots being 8-byte aligned!
56 To resolve this, we move the location of $31 to the last slot
57 in the jmp_buf when the overall buffer is 8-byte aligned. $31
58 is simply loaded/stored twice to avoid adding complexity to the
59 GPR_LAYOUT macro above as well as FPR_LAYOUT.
61 The location of the last slot is index 22 which is calculated
62 from there being 11 GPRs saved and then 12 FPRs saved so the
63 index of the last FPR is 11+11.
65 The base of the jmp_buf is modified in $4 to allow the
66 FPR_OFFSET macros to just use the usual constant slot numbers
67 regardless of whether the realignment happened or not. */
72 GPR_OFFSET ($31, 22); \
75 FPR_OFFSET ($f20, 0); \
76 FPR_OFFSET ($f22, 2); \
77 FPR_OFFSET ($f24, 4); \
78 FPR_OFFSET ($f26, 6); \
79 FPR_OFFSET ($f28, 8); \
80 FPR_OFFSET ($f30, 10);
81 #else /* Assuming _MIPS_SIM == _ABIO32 */
83 FPR_OFFSET ($f20, 0); \
84 FPR_OFFSET ($f21, 1); \
85 FPR_OFFSET ($f22, 2); \
86 FPR_OFFSET ($f23, 3); \
87 FPR_OFFSET ($f24, 4); \
88 FPR_OFFSET ($f25, 5); \
89 FPR_OFFSET ($f26, 6); \
90 FPR_OFFSET ($f27, 7); \
91 FPR_OFFSET ($f28, 8); \
92 FPR_OFFSET ($f29, 9); \
93 FPR_OFFSET ($f30, 10); \
94 FPR_OFFSET ($f31, 11);
101 #define BYTES_PER_WORD 8
103 #define LOAD_FPR ldc1
105 #define STORE_FPR sdc1
109 #define BYTES_PER_WORD 4
110 #if __mips_fpr == 0 || __mips_fpr == 64
111 #define LOAD_FPR ldc1
112 #define STORE_FPR sdc1
114 #define LOAD_FPR lwc1
115 #define STORE_FPR swc1
119 #define GPOFF(INDEX) (INDEX * BYTES_PER_WORD)
120 #define FPOFF(INDEX) ((INDEX + NUM_GPRS_SAVED) * BYTES_PER_WORD)
122 /* int setjmp (jmp_buf); */
128 #define GPR_OFFSET(REG, INDEX) STORE_GPR REG,GPOFF(INDEX)($4)
129 #define FPR_OFFSET(REG, INDEX) STORE_FPR REG,FPOFF(INDEX)($4)
140 /* volatile void longjmp (jmp_buf, int); */
146 #define GPR_OFFSET(REG, INDEX) LOAD_GPR REG,GPOFF(INDEX)($4)
147 #define FPR_OFFSET(REG, INDEX) LOAD_FPR REG,FPOFF(INDEX)($4)