5 #include <linux/types.h>
6 #include <linux/sched.h>
8 #include <asm/uaccess.h>
11 #include <asm/sfp-machine.h>
14 #define FLOATFUNC(x) extern int x(void *, void *, void *, void *)
102 #define FNMSUBS 0x01e
103 #define FNMADDS 0x01f
113 #define FRSQRTE 0x01a
153 #ifdef CONFIG_MATH_EMULATION
174 fpscr |= FPSCR_VXSNAN;
176 fpscr |= FPSCR_VXISI;
178 fpscr |= FPSCR_VXIDI;
180 fpscr |= FPSCR_VXZDZ;
182 fpscr |= FPSCR_VXIMZ;
186 fpscr |= FPSCR_VXSOFT;
188 fpscr |= FPSCR_VXSQRT;
190 fpscr |= FPSCR_VXCVI;
194 if (fpscr & (FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI |
195 FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
196 FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI))
199 fpscr &= ~(FPSCR_FEX);
200 if (((fpscr & FPSCR_VX) && (fpscr & FPSCR_VE)) ||
201 ((fpscr & FPSCR_OX) && (fpscr & FPSCR_OE)) ||
202 ((fpscr & FPSCR_UX) && (fpscr & FPSCR_UE)) ||
203 ((fpscr & FPSCR_ZX) && (fpscr & FPSCR_ZE)) ||
204 ((fpscr & FPSCR_XX) && (fpscr & FPSCR_XE)))
209 return (fpscr & FPSCR_FEX) ? 1 : 0;
216 void *op0 = 0, *op1 = 0, *op2 = 0, *op3 = 0;
217 unsigned long pc = regs->
nip;
221 #ifdef CONFIG_MATH_EMULATION
222 int (*
func)(
void *,
void *,
void *,
void *);
230 #ifndef CONFIG_MATH_EMULATION
231 switch (insn >> 26) {
233 idx = (insn >> 16) & 0x1f;
234 sdisp = (insn & 0xffff);
235 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
236 op1 = (
void *)((idx ? regs->
gpr[idx] : 0) + sdisp);
237 lfd(op0, op1, op2, op3);
240 idx = (insn >> 16) & 0x1f;
241 sdisp = (insn & 0xffff);
242 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
243 op1 = (
void *)((idx ? regs->
gpr[idx] : 0) + sdisp);
244 lfd(op0, op1, op2, op3);
248 idx = (insn >> 16) & 0x1f;
249 sdisp = (insn & 0xffff);
250 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
251 op1 = (
void *)((idx ? regs->
gpr[idx] : 0) + sdisp);
252 stfd(op0, op1, op2, op3);
255 idx = (insn >> 16) & 0x1f;
256 sdisp = (insn & 0xffff);
257 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
258 op1 = (
void *)((idx ? regs->
gpr[idx] : 0) + sdisp);
259 stfd(op0, op1, op2, op3);
263 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
264 op1 = (
void *)&
current->thread.TS_FPR((insn >> 11) & 0x1f);
265 fmr(op0, op1, op2, op3);
271 switch (insn >> 26) {
282 switch ((insn >> 1) & 0x3ff) {
298 switch ((insn >> 1) & 0x1f) {
316 switch ((insn >> 1) & 0x1f) {
334 switch ((insn >> 1) & 0x3ff) {
361 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
362 op1 = (
void *)&
current->thread.TS_FPR((insn >> 16) & 0x1f);
363 op2 = (
void *)&
current->thread.TS_FPR((insn >> 11) & 0x1f);
367 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
368 op1 = (
void *)&
current->thread.TS_FPR((insn >> 16) & 0x1f);
369 op2 = (
void *)&
current->thread.TS_FPR((insn >> 6) & 0x1f);
373 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
374 op1 = (
void *)&
current->thread.TS_FPR((insn >> 16) & 0x1f);
375 op2 = (
void *)&
current->thread.TS_FPR((insn >> 11) & 0x1f);
376 op3 = (
void *)&
current->thread.TS_FPR((insn >> 6) & 0x1f);
380 idx = (insn >> 16) & 0x1f;
381 sdisp = (insn & 0xffff);
382 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
383 op1 = (
void *)((idx ? regs->
gpr[idx] : 0) + sdisp);
387 idx = (insn >> 16) & 0x1f;
391 sdisp = (insn & 0xffff);
392 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
393 op1 = (
void *)(regs->
gpr[idx] + sdisp);
397 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
401 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
402 op1 = (
void *)&
current->thread.TS_FPR((insn >> 16) & 0x1f);
406 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
407 op1 = (
void *)&
current->thread.TS_FPR((insn >> 11) & 0x1f);
411 idx = (insn >> 16) & 0x1f;
412 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
414 if (((insn >> 1) & 0x3ff) ==
STFIWX)
415 op1 = (
void *)(regs->
gpr[(insn >> 11) & 0x1f]);
419 op1 = (
void *)(regs->
gpr[idx] + regs->
gpr[(insn >> 11) & 0x1f]);
425 idx = (insn >> 16) & 0x1f;
426 op0 = (
void *)&
current->thread.TS_FPR((insn >> 21) & 0x1f);
427 op1 = (
void *)((idx ? regs->
gpr[idx] : 0)
428 + regs->
gpr[(insn >> 11) & 0x1f]);
432 op0 = (
void *)®s->
ccr;
433 op1 = (
void *)((insn >> 23) & 0x7);
434 op2 = (
void *)&
current->thread.TS_FPR((insn >> 16) & 0x1f);
435 op3 = (
void *)&
current->thread.TS_FPR((insn >> 11) & 0x1f);
439 op0 = (
void *)®s->
ccr;
440 op1 = (
void *)((insn >> 23) & 0x7);
441 op2 = (
void *)((insn >> 18) & 0x7);
445 op0 = (
void *)((insn >> 21) & 0x1f);
449 op0 = (
void *)((insn >> 23) & 0x7);
450 op1 = (
void *)((insn >> 12) & 0xf);
454 op0 = (
void *)((insn >> 17) & 0xff);
455 op1 = (
void *)&
current->thread.TS_FPR((insn >> 11) & 0x1f);
462 eflag =
func(op0, op1, op2, op3);
465 regs->
ccr &= ~(0x0f000000);
469 trap = record_exception(regs, eflag);