Deleted Added
full compact
fpu.c (94254) fpu.c (95587)
1/*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *

--- 53 unchanged lines hidden (view full) ---

62 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
63 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 * @(#)fpu.c 8.1 (Berkeley) 6/11/93
66 * $NetBSD: fpu.c,v 1.11 2000/12/06 01:47:50 mrg Exp $
67 */
68
69#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *

--- 53 unchanged lines hidden (view full) ---

62 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
63 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 * @(#)fpu.c 8.1 (Berkeley) 6/11/93
66 * $NetBSD: fpu.c,v 1.11 2000/12/06 01:47:50 mrg Exp $
67 */
68
69#include <sys/cdefs.h>
70__FBSDID("$FreeBSD: head/lib/libc/sparc64/fpu/fpu.c 94254 2002-04-09 00:57:23Z jake $");
70__FBSDID("$FreeBSD: head/lib/libc/sparc64/fpu/fpu.c 95587 2002-04-27 21:56:28Z jake $");
71
72#include <sys/param.h>
73
74#include "namespace.h"
75#include <errno.h>
76#include <unistd.h>
77#include <signal.h>
78#include <stdlib.h>
79#include "un-namespace.h"
80#include "libc_private.h"
81
82#include <machine/emul.h>
83#include <machine/fp.h>
84#include <machine/frame.h>
85#include <machine/fsr.h>
86#include <machine/instr.h>
87#include <machine/pcb.h>
88#include <machine/tstate.h>
89
71
72#include <sys/param.h>
73
74#include "namespace.h"
75#include <errno.h>
76#include <unistd.h>
77#include <signal.h>
78#include <stdlib.h>
79#include "un-namespace.h"
80#include "libc_private.h"
81
82#include <machine/emul.h>
83#include <machine/fp.h>
84#include <machine/frame.h>
85#include <machine/fsr.h>
86#include <machine/instr.h>
87#include <machine/pcb.h>
88#include <machine/tstate.h>
89
90#include "../sys/__sparc_utrap_private.h"
90#include "__sparc_utrap_private.h"
91#include "fpu_emu.h"
92#include "fpu_extern.h"
93
94/*
95 * Translate current exceptions into `first' exception. The
96 * bits go the wrong way for ffs() (0x10 is most important, etc).
97 * There are only 5, so do it the obvious way.
98 */

--- 15 unchanged lines hidden (view full) ---

114#ifdef FPU_DEBUG_MASK
115int __fpe_debug = FPU_DEBUG_MASK;
116#else
117int __fpe_debug = 0;
118#endif
119#endif /* FPU_DEBUG */
120
121static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, u_long);
91#include "fpu_emu.h"
92#include "fpu_extern.h"
93
94/*
95 * Translate current exceptions into `first' exception. The
96 * bits go the wrong way for ffs() (0x10 is most important, etc).
97 * There are only 5, so do it the obvious way.
98 */

--- 15 unchanged lines hidden (view full) ---

114#ifdef FPU_DEBUG_MASK
115int __fpe_debug = FPU_DEBUG_MASK;
116#else
117int __fpe_debug = 0;
118#endif
119#endif /* FPU_DEBUG */
120
121static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, u_long);
122static void utrap_write(char *);
123static void utrap_kill_self(int);
124
125/*
122
123/*
126 * System call wrappers usable in an utrap environment.
127 */
128static void
129utrap_write(char *str)
130{
131 int berrno;
132
133 berrno = errno;
134 __sys_write(STDERR_FILENO, str, strlen(str));
135 errno = berrno;
136}
137
138static void
139utrap_kill_self(sig)
140{
141 int berrno;
142
143 berrno = errno;
144 __sys_kill(__sys_getpid(), sig);
145 errno = berrno;
146}
147
148void
149__fpu_panic(char *msg)
150{
151
152 utrap_write(msg);
153 utrap_write("\n");
154 utrap_kill_self(SIGKILL);
155}
156
157/*
158 * Need to use an fpstate on the stack; we could switch, so we cannot safely
159 * modify the pcb one, it might get overwritten.
160 */
124 * Need to use an fpstate on the stack; we could switch, so we cannot safely
125 * modify the pcb one, it might get overwritten.
126 */
161void
127int
162__fpu_exception(struct utrapframe *uf)
163{
164 struct fpemu fe;
165 u_long fsr, tstate;
166 u_int insn;
128__fpu_exception(struct utrapframe *uf)
129{
130 struct fpemu fe;
131 u_long fsr, tstate;
132 u_int insn;
167 int rv;
133 int sig;
168
169 fsr = uf->uf_fsr;
170
171 switch (FSR_GET_FTT(fsr)) {
172 case FSR_FTT_NONE:
134
135 fsr = uf->uf_fsr;
136
137 switch (FSR_GET_FTT(fsr)) {
138 case FSR_FTT_NONE:
173 utrap_write("lost FPU trap type\n");
174 return;
139 __utrap_write("lost FPU trap type\n");
140 return (0);
175 case FSR_FTT_IEEE:
141 case FSR_FTT_IEEE:
176 goto fatal;
142 return (SIGFPE);
177 case FSR_FTT_SEQERR:
143 case FSR_FTT_SEQERR:
178 utrap_write("FPU sequence error\n");
179 goto fatal;
144 __utrap_write("FPU sequence error\n");
145 return (SIGFPE);
180 case FSR_FTT_HWERR:
146 case FSR_FTT_HWERR:
181 utrap_write("FPU hardware error\n");
182 goto fatal;
147 __utrap_write("FPU hardware error\n");
148 return (SIGFPE);
183 case FSR_FTT_UNFIN:
184 case FSR_FTT_UNIMP:
185 break;
186 default:
149 case FSR_FTT_UNFIN:
150 case FSR_FTT_UNIMP:
151 break;
152 default:
187 utrap_write("unknown FPU error\n");
188 goto fatal;
153 __utrap_write("unknown FPU error\n");
154 return (SIGFPE);
189 }
190
191 fe.fe_fsr = fsr & ~FSR_FTT_MASK;
192 insn = *(u_int32_t *)uf->uf_pc;
193 if (IF_OP(insn) != IOP_MISC || (IF_F3_OP3(insn) != INS2_FPop1 &&
194 IF_F3_OP3(insn) != INS2_FPop2))
155 }
156
157 fe.fe_fsr = fsr & ~FSR_FTT_MASK;
158 insn = *(u_int32_t *)uf->uf_pc;
159 if (IF_OP(insn) != IOP_MISC || (IF_F3_OP3(insn) != INS2_FPop1 &&
160 IF_F3_OP3(insn) != INS2_FPop2))
195 __fpu_panic("bogus FP fault");
161 __utrap_panic("bogus FP fault");
196 tstate = uf->uf_state;
162 tstate = uf->uf_state;
197 rv = __fpu_execute(uf, &fe, insn, tstate);
198 if (rv != 0)
199 utrap_kill_self(rv);
163 sig = __fpu_execute(uf, &fe, insn, tstate);
164 if (sig != 0)
165 return (sig);
200 __asm __volatile("ldx %0, %%fsr" : : "m" (fe.fe_fsr));
166 __asm __volatile("ldx %0, %%fsr" : : "m" (fe.fe_fsr));
201 return;
202fatal:
203 utrap_kill_self(SIGFPE);
204 return;
167 return (0);
205}
206
207#ifdef FPU_DEBUG
208/*
209 * Dump a `fpn' structure.
210 */
211void
212__fpu_dumpfpn(struct fpn *fp)

--- 5 unchanged lines hidden (view full) ---

218 printf("%s %c.%x %x %x %xE%d", class[fp->fp_class + 2],
219 fp->fp_sign ? '-' : ' ',
220 fp->fp_mant[0], fp->fp_mant[1],
221 fp->fp_mant[2], fp->fp_mant[3],
222 fp->fp_exp);
223}
224#endif
225
168}
169
170#ifdef FPU_DEBUG
171/*
172 * Dump a `fpn' structure.
173 */
174void
175__fpu_dumpfpn(struct fpn *fp)

--- 5 unchanged lines hidden (view full) ---

181 printf("%s %c.%x %x %x %xE%d", class[fp->fp_class + 2],
182 fp->fp_sign ? '-' : ' ',
183 fp->fp_mant[0], fp->fp_mant[1],
184 fp->fp_mant[2], fp->fp_mant[3],
185 fp->fp_exp);
186}
187#endif
188
226static u_long
227fetch_reg(struct utrapframe *uf, int reg)
228{
229 u_long offs;
230 struct frame *frm;
231
232 if (reg == IREG_G0)
233 return (0);
234 else if (reg < IREG_O0) /* global */
235 return (uf->uf_global[reg]);
236 else if (reg < IREG_L0) /* out */
237 return (uf->uf_out[reg - IREG_O0]);
238 else { /* local, in */
239 /*
240 * The in registers are immediately after the locals in
241 * the frame.
242 */
243 frm = (struct frame *)(uf->uf_out[6] + SPOFF);
244 return (frm->fr_local[reg - IREG_L0]);
245 }
246 __fpu_panic("fetch_reg: bogus register");
247}
248
249static void
250__fpu_mov(struct fpemu *fe, int type, int rd, int rs1, int rs2)
251{
252 int i;
253
254 i = 1 << type;
255 __fpu_setreg(rd++, rs1);
256 while (--i)

--- 99 unchanged lines hidden (view full) ---

356 __fpu_ccmov(fe, type, rd, __fpu_getreg(rs2), rs2, insn,
357 (tstate & TSTATE_ICC_MASK) >> TSTATE_ICC_SHIFT);
358 return (0);
359 case FOP(INS2_FPop2, INSFP2_FMOV_CC(IFCC_XCC)):
360 __fpu_ccmov(fe, type, rd, __fpu_getreg(rs2), rs2, insn,
361 (tstate & TSTATE_XCC_MASK) >> (TSTATE_XCC_SHIFT));
362 return (0);
363 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_Z)):
189static void
190__fpu_mov(struct fpemu *fe, int type, int rd, int rs1, int rs2)
191{
192 int i;
193
194 i = 1 << type;
195 __fpu_setreg(rd++, rs1);
196 while (--i)

--- 99 unchanged lines hidden (view full) ---

296 __fpu_ccmov(fe, type, rd, __fpu_getreg(rs2), rs2, insn,
297 (tstate & TSTATE_ICC_MASK) >> TSTATE_ICC_SHIFT);
298 return (0);
299 case FOP(INS2_FPop2, INSFP2_FMOV_CC(IFCC_XCC)):
300 __fpu_ccmov(fe, type, rd, __fpu_getreg(rs2), rs2, insn,
301 (tstate & TSTATE_XCC_MASK) >> (TSTATE_XCC_SHIFT));
302 return (0);
303 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_Z)):
364 reg = fetch_reg(uf, IF_F4_RS1(insn));
304 reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
365 if (reg == 0)
366 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
367 return (0);
368 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_LEZ)):
305 if (reg == 0)
306 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
307 return (0);
308 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_LEZ)):
369 reg = fetch_reg(uf, IF_F4_RS1(insn));
309 reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
370 if (reg <= 0)
371 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
372 return (0);
373 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_LZ)):
310 if (reg <= 0)
311 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
312 return (0);
313 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_LZ)):
374 reg = fetch_reg(uf, IF_F4_RS1(insn));
314 reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
375 if (reg < 0)
376 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
377 return (0);
378 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_NZ)):
315 if (reg < 0)
316 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
317 return (0);
318 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_NZ)):
379 reg = fetch_reg(uf, IF_F4_RS1(insn));
319 reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
380 if (reg != 0)
381 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
382 return (0);
383 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_GZ)):
320 if (reg != 0)
321 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
322 return (0);
323 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_GZ)):
384 reg = fetch_reg(uf, IF_F4_RS1(insn));
324 reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
385 if (reg > 0)
386 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
387 return (0);
388 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_GEZ)):
325 if (reg > 0)
326 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
327 return (0);
328 case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_GEZ)):
389 reg = fetch_reg(uf, IF_F4_RS1(insn));
329 reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
390 if (reg >= 0)
391 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
392 return (0);
393 case FOP(INS2_FPop2, INSFP2_FCMP):
394 __fpu_explode(fe, &fe->fe_f1, type, rs1);
395 __fpu_explode(fe, &fe->fe_f2, type, rs2);
396 __fpu_compare(fe, 0, IF_F3_CC(insn));
397 return (__fpu_cmpck(fe));

--- 113 unchanged lines hidden ---
330 if (reg >= 0)
331 __fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
332 return (0);
333 case FOP(INS2_FPop2, INSFP2_FCMP):
334 __fpu_explode(fe, &fe->fe_f1, type, rs1);
335 __fpu_explode(fe, &fe->fe_f2, type, rs2);
336 __fpu_compare(fe, 0, IF_F3_CC(insn));
337 return (__fpu_cmpck(fe));

--- 113 unchanged lines hidden ---