xref: /linux/arch/mips/math-emu/cp1emu.c (revision 9b8b317d58084b9a44f6f33b355c4278d9f841fb)
1 /*
2  * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
3  *
4  * MIPS floating point support
5  * Copyright (C) 1994-2000 Algorithmics Ltd.
6  * http://www.algor.co.uk
7  *
8  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
9  * Copyright (C) 2000  MIPS Technologies, Inc.
10  *
11  *  This program is free software; you can distribute it and/or modify it
12  *  under the terms of the GNU General Public License (Version 2) as
13  *  published by the Free Software Foundation.
14  *
15  *  This program is distributed in the hope it will be useful, but WITHOUT
16  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18  *  for more details.
19  *
20  *  You should have received a copy of the GNU General Public License along
21  *  with this program; if not, write to the Free Software Foundation, Inc.,
22  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23  *
24  * A complete emulator for MIPS coprocessor 1 instructions.  This is
25  * required for #float(switch) or #float(trap), where it catches all
26  * COP1 instructions via the "CoProcessor Unusable" exception.
27  *
28  * More surprisingly it is also required for #float(ieee), to help out
29  * the hardware fpu at the boundaries of the IEEE-754 representation
30  * (denormalised values, infinities, underflow, etc).  It is made
31  * quite nasty because emulation of some non-COP1 instructions is
32  * required, e.g. in branch delay slots.
33  *
34  * Note if you know that you won't have an fpu, then you'll get much
35  * better performance by compiling with -msoft-float!
36  */
37 #include <linux/sched.h>
38 #include <linux/debugfs.h>
39 
40 #include <asm/inst.h>
41 #include <asm/bootinfo.h>
42 #include <asm/processor.h>
43 #include <asm/ptrace.h>
44 #include <asm/signal.h>
45 #include <asm/mipsregs.h>
46 #include <asm/fpu_emulator.h>
47 #include <asm/uaccess.h>
48 #include <asm/branch.h>
49 
50 #include "ieee754.h"
51 
52 /* Strap kernel emulator for full MIPS IV emulation */
53 
54 #ifdef __mips
55 #undef __mips
56 #endif
57 #define __mips 4
58 
59 /* Function which emulates a floating point instruction. */
60 
61 static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
62 	mips_instruction);
63 
64 #if __mips >= 4 && __mips != 32
65 static int fpux_emu(struct pt_regs *,
66 	struct mips_fpu_struct *, mips_instruction);
67 #endif
68 
69 /* Further private data for which no space exists in mips_fpu_struct */
70 
71 struct mips_fpu_emulator_stats fpuemustats;
72 
73 /* Control registers */
74 
75 #define FPCREG_RID	0	/* $0  = revision id */
76 #define FPCREG_CSR	31	/* $31 = csr */
77 
78 /* Convert Mips rounding mode (0..3) to IEEE library modes. */
79 static const unsigned char ieee_rm[4] = {
80 	[FPU_CSR_RN] = IEEE754_RN,
81 	[FPU_CSR_RZ] = IEEE754_RZ,
82 	[FPU_CSR_RU] = IEEE754_RU,
83 	[FPU_CSR_RD] = IEEE754_RD,
84 };
85 /* Convert IEEE library modes to Mips rounding mode (0..3). */
86 static const unsigned char mips_rm[4] = {
87 	[IEEE754_RN] = FPU_CSR_RN,
88 	[IEEE754_RZ] = FPU_CSR_RZ,
89 	[IEEE754_RD] = FPU_CSR_RD,
90 	[IEEE754_RU] = FPU_CSR_RU,
91 };
92 
93 #if __mips >= 4
94 /* convert condition code register number to csr bit */
95 static const unsigned int fpucondbit[8] = {
96 	FPU_CSR_COND0,
97 	FPU_CSR_COND1,
98 	FPU_CSR_COND2,
99 	FPU_CSR_COND3,
100 	FPU_CSR_COND4,
101 	FPU_CSR_COND5,
102 	FPU_CSR_COND6,
103 	FPU_CSR_COND7
104 };
105 #endif
106 
107 
108 /*
109  * Redundant with logic already in kernel/branch.c,
110  * embedded in compute_return_epc.  At some point,
111  * a single subroutine should be used across both
112  * modules.
113  */
114 static int isBranchInstr(mips_instruction * i)
115 {
116 	switch (MIPSInst_OPCODE(*i)) {
117 	case spec_op:
118 		switch (MIPSInst_FUNC(*i)) {
119 		case jalr_op:
120 		case jr_op:
121 			return 1;
122 		}
123 		break;
124 
125 	case bcond_op:
126 		switch (MIPSInst_RT(*i)) {
127 		case bltz_op:
128 		case bgez_op:
129 		case bltzl_op:
130 		case bgezl_op:
131 		case bltzal_op:
132 		case bgezal_op:
133 		case bltzall_op:
134 		case bgezall_op:
135 			return 1;
136 		}
137 		break;
138 
139 	case j_op:
140 	case jal_op:
141 	case jalx_op:
142 	case beq_op:
143 	case bne_op:
144 	case blez_op:
145 	case bgtz_op:
146 	case beql_op:
147 	case bnel_op:
148 	case blezl_op:
149 	case bgtzl_op:
150 		return 1;
151 
152 	case cop0_op:
153 	case cop1_op:
154 	case cop2_op:
155 	case cop1x_op:
156 		if (MIPSInst_RS(*i) == bc_op)
157 			return 1;
158 		break;
159 	}
160 
161 	return 0;
162 }
163 
164 /*
165  * In the Linux kernel, we support selection of FPR format on the
166  * basis of the Status.FR bit.  If an FPU is not present, the FR bit
167  * is hardwired to zero, which would imply a 32-bit FPU even for
168  * 64-bit CPUs.  For 64-bit kernels with no FPU we use TIF_32BIT_REGS
169  * as a proxy for the FR bit so that a 64-bit FPU is emulated.  In any
170  * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the
171  * even FPRs are used (Status.FR = 0).
172  */
173 static inline int cop1_64bit(struct pt_regs *xcp)
174 {
175 	if (cpu_has_fpu)
176 		return xcp->cp0_status & ST0_FR;
177 #ifdef CONFIG_64BIT
178 	return !test_thread_flag(TIF_32BIT_REGS);
179 #else
180 	return 0;
181 #endif
182 }
183 
184 #define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
185 			(int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
186 
187 #define SITOREG(si, x)	(ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
188 			cop1_64bit(xcp) || !(x & 1) ? \
189 			ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
190 			ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
191 
192 #define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
193 #define DITOREG(di, x)	(ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
194 
195 #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
196 #define SPTOREG(sp, x)	SITOREG((sp).bits, x)
197 #define DPFROMREG(dp, x)	DIFROMREG((dp).bits, x)
198 #define DPTOREG(dp, x)	DITOREG((dp).bits, x)
199 
200 /*
201  * Emulate the single floating point instruction pointed at by EPC.
202  * Two instructions if the instruction is in a branch delay slot.
203  */
204 
205 static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
206 {
207 	mips_instruction ir;
208 	unsigned long emulpc, contpc;
209 	unsigned int cond;
210 
211 	if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
212 		fpuemustats.errors++;
213 		return SIGBUS;
214 	}
215 
216 	/* XXX NEC Vr54xx bug workaround */
217 	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
218 		xcp->cp0_cause &= ~CAUSEF_BD;
219 
220 	if (xcp->cp0_cause & CAUSEF_BD) {
221 		/*
222 		 * The instruction to be emulated is in a branch delay slot
223 		 * which means that we have to  emulate the branch instruction
224 		 * BEFORE we do the cop1 instruction.
225 		 *
226 		 * This branch could be a COP1 branch, but in that case we
227 		 * would have had a trap for that instruction, and would not
228 		 * come through this route.
229 		 *
230 		 * Linux MIPS branch emulator operates on context, updating the
231 		 * cp0_epc.
232 		 */
233 		emulpc = xcp->cp0_epc + 4;	/* Snapshot emulation target */
234 
235 		if (__compute_return_epc(xcp)) {
236 #ifdef CP1DBG
237 			printk("failed to emulate branch at %p\n",
238 				(void *) (xcp->cp0_epc));
239 #endif
240 			return SIGILL;
241 		}
242 		if (get_user(ir, (mips_instruction __user *) emulpc)) {
243 			fpuemustats.errors++;
244 			return SIGBUS;
245 		}
246 		/* __compute_return_epc() will have updated cp0_epc */
247 		contpc = xcp->cp0_epc;
248 		/* In order not to confuse ptrace() et al, tweak context */
249 		xcp->cp0_epc = emulpc - 4;
250 	} else {
251 		emulpc = xcp->cp0_epc;
252 		contpc = xcp->cp0_epc + 4;
253 	}
254 
255       emul:
256 	fpuemustats.emulated++;
257 	switch (MIPSInst_OPCODE(ir)) {
258 	case ldc1_op:{
259 		u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
260 			MIPSInst_SIMM(ir));
261 		u64 val;
262 
263 		fpuemustats.loads++;
264 		if (get_user(val, va)) {
265 			fpuemustats.errors++;
266 			return SIGBUS;
267 		}
268 		DITOREG(val, MIPSInst_RT(ir));
269 		break;
270 	}
271 
272 	case sdc1_op:{
273 		u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
274 			MIPSInst_SIMM(ir));
275 		u64 val;
276 
277 		fpuemustats.stores++;
278 		DIFROMREG(val, MIPSInst_RT(ir));
279 		if (put_user(val, va)) {
280 			fpuemustats.errors++;
281 			return SIGBUS;
282 		}
283 		break;
284 	}
285 
286 	case lwc1_op:{
287 		u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
288 			MIPSInst_SIMM(ir));
289 		u32 val;
290 
291 		fpuemustats.loads++;
292 		if (get_user(val, va)) {
293 			fpuemustats.errors++;
294 			return SIGBUS;
295 		}
296 		SITOREG(val, MIPSInst_RT(ir));
297 		break;
298 	}
299 
300 	case swc1_op:{
301 		u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
302 			MIPSInst_SIMM(ir));
303 		u32 val;
304 
305 		fpuemustats.stores++;
306 		SIFROMREG(val, MIPSInst_RT(ir));
307 		if (put_user(val, va)) {
308 			fpuemustats.errors++;
309 			return SIGBUS;
310 		}
311 		break;
312 	}
313 
314 	case cop1_op:
315 		switch (MIPSInst_RS(ir)) {
316 
317 #if defined(__mips64)
318 		case dmfc_op:
319 			/* copregister fs -> gpr[rt] */
320 			if (MIPSInst_RT(ir) != 0) {
321 				DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
322 					MIPSInst_RD(ir));
323 			}
324 			break;
325 
326 		case dmtc_op:
327 			/* copregister fs <- rt */
328 			DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
329 			break;
330 #endif
331 
332 		case mfc_op:
333 			/* copregister rd -> gpr[rt] */
334 			if (MIPSInst_RT(ir) != 0) {
335 				SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
336 					MIPSInst_RD(ir));
337 			}
338 			break;
339 
340 		case mtc_op:
341 			/* copregister rd <- rt */
342 			SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
343 			break;
344 
345 		case cfc_op:{
346 			/* cop control register rd -> gpr[rt] */
347 			u32 value;
348 
349 			if (MIPSInst_RD(ir) == FPCREG_CSR) {
350 				value = ctx->fcr31;
351 				value = (value & ~0x3) | mips_rm[value & 0x3];
352 #ifdef CSRTRACE
353 				printk("%p gpr[%d]<-csr=%08x\n",
354 					(void *) (xcp->cp0_epc),
355 					MIPSInst_RT(ir), value);
356 #endif
357 			}
358 			else if (MIPSInst_RD(ir) == FPCREG_RID)
359 				value = 0;
360 			else
361 				value = 0;
362 			if (MIPSInst_RT(ir))
363 				xcp->regs[MIPSInst_RT(ir)] = value;
364 			break;
365 		}
366 
367 		case ctc_op:{
368 			/* copregister rd <- rt */
369 			u32 value;
370 
371 			if (MIPSInst_RT(ir) == 0)
372 				value = 0;
373 			else
374 				value = xcp->regs[MIPSInst_RT(ir)];
375 
376 			/* we only have one writable control reg
377 			 */
378 			if (MIPSInst_RD(ir) == FPCREG_CSR) {
379 #ifdef CSRTRACE
380 				printk("%p gpr[%d]->csr=%08x\n",
381 					(void *) (xcp->cp0_epc),
382 					MIPSInst_RT(ir), value);
383 #endif
384 				value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
385 				ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
386 				/* convert to ieee library modes */
387 				ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
388 			}
389 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
390 				return SIGFPE;
391 			}
392 			break;
393 		}
394 
395 		case bc_op:{
396 			int likely = 0;
397 
398 			if (xcp->cp0_cause & CAUSEF_BD)
399 				return SIGILL;
400 
401 #if __mips >= 4
402 			cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2];
403 #else
404 			cond = ctx->fcr31 & FPU_CSR_COND;
405 #endif
406 			switch (MIPSInst_RT(ir) & 3) {
407 			case bcfl_op:
408 				likely = 1;
409 			case bcf_op:
410 				cond = !cond;
411 				break;
412 			case bctl_op:
413 				likely = 1;
414 			case bct_op:
415 				break;
416 			default:
417 				/* thats an illegal instruction */
418 				return SIGILL;
419 			}
420 
421 			xcp->cp0_cause |= CAUSEF_BD;
422 			if (cond) {
423 				/* branch taken: emulate dslot
424 				 * instruction
425 				 */
426 				xcp->cp0_epc += 4;
427 				contpc = (xcp->cp0_epc +
428 					(MIPSInst_SIMM(ir) << 2));
429 
430 				if (get_user(ir,
431 				    (mips_instruction __user *) xcp->cp0_epc)) {
432 					fpuemustats.errors++;
433 					return SIGBUS;
434 				}
435 
436 				switch (MIPSInst_OPCODE(ir)) {
437 				case lwc1_op:
438 				case swc1_op:
439 #if (__mips >= 2 || defined(__mips64))
440 				case ldc1_op:
441 				case sdc1_op:
442 #endif
443 				case cop1_op:
444 #if __mips >= 4 && __mips != 32
445 				case cop1x_op:
446 #endif
447 					/* its one of ours */
448 					goto emul;
449 #if __mips >= 4
450 				case spec_op:
451 					if (MIPSInst_FUNC(ir) == movc_op)
452 						goto emul;
453 					break;
454 #endif
455 				}
456 
457 				/*
458 				 * Single step the non-cp1
459 				 * instruction in the dslot
460 				 */
461 				return mips_dsemul(xcp, ir, contpc);
462 			}
463 			else {
464 				/* branch not taken */
465 				if (likely) {
466 					/*
467 					 * branch likely nullifies
468 					 * dslot if not taken
469 					 */
470 					xcp->cp0_epc += 4;
471 					contpc += 4;
472 					/*
473 					 * else continue & execute
474 					 * dslot as normal insn
475 					 */
476 				}
477 			}
478 			break;
479 		}
480 
481 		default:
482 			if (!(MIPSInst_RS(ir) & 0x10))
483 				return SIGILL;
484 			{
485 				int sig;
486 
487 				/* a real fpu computation instruction */
488 				if ((sig = fpu_emu(xcp, ctx, ir)))
489 					return sig;
490 			}
491 		}
492 		break;
493 
494 #if __mips >= 4 && __mips != 32
495 	case cop1x_op:{
496 		int sig;
497 
498 		if ((sig = fpux_emu(xcp, ctx, ir)))
499 			return sig;
500 		break;
501 	}
502 #endif
503 
504 #if __mips >= 4
505 	case spec_op:
506 		if (MIPSInst_FUNC(ir) != movc_op)
507 			return SIGILL;
508 		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
509 		if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
510 			xcp->regs[MIPSInst_RD(ir)] =
511 				xcp->regs[MIPSInst_RS(ir)];
512 		break;
513 #endif
514 
515 	default:
516 		return SIGILL;
517 	}
518 
519 	/* we did it !! */
520 	xcp->cp0_epc = contpc;
521 	xcp->cp0_cause &= ~CAUSEF_BD;
522 
523 	return 0;
524 }
525 
526 /*
527  * Conversion table from MIPS compare ops 48-63
528  * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
529  */
530 static const unsigned char cmptab[8] = {
531 	0,			/* cmp_0 (sig) cmp_sf */
532 	IEEE754_CUN,		/* cmp_un (sig) cmp_ngle */
533 	IEEE754_CEQ,		/* cmp_eq (sig) cmp_seq */
534 	IEEE754_CEQ | IEEE754_CUN,	/* cmp_ueq (sig) cmp_ngl  */
535 	IEEE754_CLT,		/* cmp_olt (sig) cmp_lt */
536 	IEEE754_CLT | IEEE754_CUN,	/* cmp_ult (sig) cmp_nge */
537 	IEEE754_CLT | IEEE754_CEQ,	/* cmp_ole (sig) cmp_le */
538 	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,	/* cmp_ule (sig) cmp_ngt */
539 };
540 
541 
542 #if __mips >= 4 && __mips != 32
543 
544 /*
545  * Additional MIPS4 instructions
546  */
547 
548 #define DEF3OP(name, p, f1, f2, f3) \
549 static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
550     ieee754##p t) \
551 { \
552 	struct _ieee754_csr ieee754_csr_save; \
553 	s = f1(s, t); \
554 	ieee754_csr_save = ieee754_csr; \
555 	s = f2(s, r); \
556 	ieee754_csr_save.cx |= ieee754_csr.cx; \
557 	ieee754_csr_save.sx |= ieee754_csr.sx; \
558 	s = f3(s); \
559 	ieee754_csr.cx |= ieee754_csr_save.cx; \
560 	ieee754_csr.sx |= ieee754_csr_save.sx; \
561 	return s; \
562 }
563 
564 static ieee754dp fpemu_dp_recip(ieee754dp d)
565 {
566 	return ieee754dp_div(ieee754dp_one(0), d);
567 }
568 
569 static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
570 {
571 	return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
572 }
573 
574 static ieee754sp fpemu_sp_recip(ieee754sp s)
575 {
576 	return ieee754sp_div(ieee754sp_one(0), s);
577 }
578 
579 static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
580 {
581 	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
582 }
583 
584 DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
585 DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
586 DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
587 DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
588 DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
589 DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
590 DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
591 DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
592 
593 static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
594 	mips_instruction ir)
595 {
596 	unsigned rcsr = 0;	/* resulting csr */
597 
598 	fpuemustats.cp1xops++;
599 
600 	switch (MIPSInst_FMA_FFMT(ir)) {
601 	case s_fmt:{		/* 0 */
602 
603 		ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
604 		ieee754sp fd, fr, fs, ft;
605 		u32 __user *va;
606 		u32 val;
607 
608 		switch (MIPSInst_FUNC(ir)) {
609 		case lwxc1_op:
610 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
611 				xcp->regs[MIPSInst_FT(ir)]);
612 
613 			fpuemustats.loads++;
614 			if (get_user(val, va)) {
615 				fpuemustats.errors++;
616 				return SIGBUS;
617 			}
618 			SITOREG(val, MIPSInst_FD(ir));
619 			break;
620 
621 		case swxc1_op:
622 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
623 				xcp->regs[MIPSInst_FT(ir)]);
624 
625 			fpuemustats.stores++;
626 
627 			SIFROMREG(val, MIPSInst_FS(ir));
628 			if (put_user(val, va)) {
629 				fpuemustats.errors++;
630 				return SIGBUS;
631 			}
632 			break;
633 
634 		case madd_s_op:
635 			handler = fpemu_sp_madd;
636 			goto scoptop;
637 		case msub_s_op:
638 			handler = fpemu_sp_msub;
639 			goto scoptop;
640 		case nmadd_s_op:
641 			handler = fpemu_sp_nmadd;
642 			goto scoptop;
643 		case nmsub_s_op:
644 			handler = fpemu_sp_nmsub;
645 			goto scoptop;
646 
647 		      scoptop:
648 			SPFROMREG(fr, MIPSInst_FR(ir));
649 			SPFROMREG(fs, MIPSInst_FS(ir));
650 			SPFROMREG(ft, MIPSInst_FT(ir));
651 			fd = (*handler) (fr, fs, ft);
652 			SPTOREG(fd, MIPSInst_FD(ir));
653 
654 		      copcsr:
655 			if (ieee754_cxtest(IEEE754_INEXACT))
656 				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
657 			if (ieee754_cxtest(IEEE754_UNDERFLOW))
658 				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
659 			if (ieee754_cxtest(IEEE754_OVERFLOW))
660 				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
661 			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
662 				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
663 
664 			ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
665 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
666 				/*printk ("SIGFPE: fpu csr = %08x\n",
667 				   ctx->fcr31); */
668 				return SIGFPE;
669 			}
670 
671 			break;
672 
673 		default:
674 			return SIGILL;
675 		}
676 		break;
677 	}
678 
679 	case d_fmt:{		/* 1 */
680 		ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
681 		ieee754dp fd, fr, fs, ft;
682 		u64 __user *va;
683 		u64 val;
684 
685 		switch (MIPSInst_FUNC(ir)) {
686 		case ldxc1_op:
687 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
688 				xcp->regs[MIPSInst_FT(ir)]);
689 
690 			fpuemustats.loads++;
691 			if (get_user(val, va)) {
692 				fpuemustats.errors++;
693 				return SIGBUS;
694 			}
695 			DITOREG(val, MIPSInst_FD(ir));
696 			break;
697 
698 		case sdxc1_op:
699 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
700 				xcp->regs[MIPSInst_FT(ir)]);
701 
702 			fpuemustats.stores++;
703 			DIFROMREG(val, MIPSInst_FS(ir));
704 			if (put_user(val, va)) {
705 				fpuemustats.errors++;
706 				return SIGBUS;
707 			}
708 			break;
709 
710 		case madd_d_op:
711 			handler = fpemu_dp_madd;
712 			goto dcoptop;
713 		case msub_d_op:
714 			handler = fpemu_dp_msub;
715 			goto dcoptop;
716 		case nmadd_d_op:
717 			handler = fpemu_dp_nmadd;
718 			goto dcoptop;
719 		case nmsub_d_op:
720 			handler = fpemu_dp_nmsub;
721 			goto dcoptop;
722 
723 		      dcoptop:
724 			DPFROMREG(fr, MIPSInst_FR(ir));
725 			DPFROMREG(fs, MIPSInst_FS(ir));
726 			DPFROMREG(ft, MIPSInst_FT(ir));
727 			fd = (*handler) (fr, fs, ft);
728 			DPTOREG(fd, MIPSInst_FD(ir));
729 			goto copcsr;
730 
731 		default:
732 			return SIGILL;
733 		}
734 		break;
735 	}
736 
737 	case 0x7:		/* 7 */
738 		if (MIPSInst_FUNC(ir) != pfetch_op) {
739 			return SIGILL;
740 		}
741 		/* ignore prefx operation */
742 		break;
743 
744 	default:
745 		return SIGILL;
746 	}
747 
748 	return 0;
749 }
750 #endif
751 
752 
753 
754 /*
755  * Emulate a single COP1 arithmetic instruction.
756  */
757 static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
758 	mips_instruction ir)
759 {
760 	int rfmt;		/* resulting format */
761 	unsigned rcsr = 0;	/* resulting csr */
762 	unsigned cond;
763 	union {
764 		ieee754dp d;
765 		ieee754sp s;
766 		int w;
767 #ifdef __mips64
768 		s64 l;
769 #endif
770 	} rv;			/* resulting value */
771 
772 	fpuemustats.cp1ops++;
773 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
774 	case s_fmt:{		/* 0 */
775 		union {
776 			ieee754sp(*b) (ieee754sp, ieee754sp);
777 			ieee754sp(*u) (ieee754sp);
778 		} handler;
779 
780 		switch (MIPSInst_FUNC(ir)) {
781 			/* binary ops */
782 		case fadd_op:
783 			handler.b = ieee754sp_add;
784 			goto scopbop;
785 		case fsub_op:
786 			handler.b = ieee754sp_sub;
787 			goto scopbop;
788 		case fmul_op:
789 			handler.b = ieee754sp_mul;
790 			goto scopbop;
791 		case fdiv_op:
792 			handler.b = ieee754sp_div;
793 			goto scopbop;
794 
795 			/* unary  ops */
796 #if __mips >= 2 || defined(__mips64)
797 		case fsqrt_op:
798 			handler.u = ieee754sp_sqrt;
799 			goto scopuop;
800 #endif
801 #if __mips >= 4 && __mips != 32
802 		case frsqrt_op:
803 			handler.u = fpemu_sp_rsqrt;
804 			goto scopuop;
805 		case frecip_op:
806 			handler.u = fpemu_sp_recip;
807 			goto scopuop;
808 #endif
809 #if __mips >= 4
810 		case fmovc_op:
811 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
812 			if (((ctx->fcr31 & cond) != 0) !=
813 				((MIPSInst_FT(ir) & 1) != 0))
814 				return 0;
815 			SPFROMREG(rv.s, MIPSInst_FS(ir));
816 			break;
817 		case fmovz_op:
818 			if (xcp->regs[MIPSInst_FT(ir)] != 0)
819 				return 0;
820 			SPFROMREG(rv.s, MIPSInst_FS(ir));
821 			break;
822 		case fmovn_op:
823 			if (xcp->regs[MIPSInst_FT(ir)] == 0)
824 				return 0;
825 			SPFROMREG(rv.s, MIPSInst_FS(ir));
826 			break;
827 #endif
828 		case fabs_op:
829 			handler.u = ieee754sp_abs;
830 			goto scopuop;
831 		case fneg_op:
832 			handler.u = ieee754sp_neg;
833 			goto scopuop;
834 		case fmov_op:
835 			/* an easy one */
836 			SPFROMREG(rv.s, MIPSInst_FS(ir));
837 			goto copcsr;
838 
839 			/* binary op on handler */
840 		      scopbop:
841 			{
842 				ieee754sp fs, ft;
843 
844 				SPFROMREG(fs, MIPSInst_FS(ir));
845 				SPFROMREG(ft, MIPSInst_FT(ir));
846 
847 				rv.s = (*handler.b) (fs, ft);
848 				goto copcsr;
849 			}
850 		      scopuop:
851 			{
852 				ieee754sp fs;
853 
854 				SPFROMREG(fs, MIPSInst_FS(ir));
855 				rv.s = (*handler.u) (fs);
856 				goto copcsr;
857 			}
858 		      copcsr:
859 			if (ieee754_cxtest(IEEE754_INEXACT))
860 				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
861 			if (ieee754_cxtest(IEEE754_UNDERFLOW))
862 				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
863 			if (ieee754_cxtest(IEEE754_OVERFLOW))
864 				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
865 			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
866 				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
867 			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
868 				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
869 			break;
870 
871 			/* unary conv ops */
872 		case fcvts_op:
873 			return SIGILL;	/* not defined */
874 		case fcvtd_op:{
875 			ieee754sp fs;
876 
877 			SPFROMREG(fs, MIPSInst_FS(ir));
878 			rv.d = ieee754dp_fsp(fs);
879 			rfmt = d_fmt;
880 			goto copcsr;
881 		}
882 		case fcvtw_op:{
883 			ieee754sp fs;
884 
885 			SPFROMREG(fs, MIPSInst_FS(ir));
886 			rv.w = ieee754sp_tint(fs);
887 			rfmt = w_fmt;
888 			goto copcsr;
889 		}
890 
891 #if __mips >= 2 || defined(__mips64)
892 		case fround_op:
893 		case ftrunc_op:
894 		case fceil_op:
895 		case ffloor_op:{
896 			unsigned int oldrm = ieee754_csr.rm;
897 			ieee754sp fs;
898 
899 			SPFROMREG(fs, MIPSInst_FS(ir));
900 			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
901 			rv.w = ieee754sp_tint(fs);
902 			ieee754_csr.rm = oldrm;
903 			rfmt = w_fmt;
904 			goto copcsr;
905 		}
906 #endif /* __mips >= 2 */
907 
908 #if defined(__mips64)
909 		case fcvtl_op:{
910 			ieee754sp fs;
911 
912 			SPFROMREG(fs, MIPSInst_FS(ir));
913 			rv.l = ieee754sp_tlong(fs);
914 			rfmt = l_fmt;
915 			goto copcsr;
916 		}
917 
918 		case froundl_op:
919 		case ftruncl_op:
920 		case fceill_op:
921 		case ffloorl_op:{
922 			unsigned int oldrm = ieee754_csr.rm;
923 			ieee754sp fs;
924 
925 			SPFROMREG(fs, MIPSInst_FS(ir));
926 			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
927 			rv.l = ieee754sp_tlong(fs);
928 			ieee754_csr.rm = oldrm;
929 			rfmt = l_fmt;
930 			goto copcsr;
931 		}
932 #endif /* defined(__mips64) */
933 
934 		default:
935 			if (MIPSInst_FUNC(ir) >= fcmp_op) {
936 				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
937 				ieee754sp fs, ft;
938 
939 				SPFROMREG(fs, MIPSInst_FS(ir));
940 				SPFROMREG(ft, MIPSInst_FT(ir));
941 				rv.w = ieee754sp_cmp(fs, ft,
942 					cmptab[cmpop & 0x7], cmpop & 0x8);
943 				rfmt = -1;
944 				if ((cmpop & 0x8) && ieee754_cxtest
945 					(IEEE754_INVALID_OPERATION))
946 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
947 				else
948 					goto copcsr;
949 
950 			}
951 			else {
952 				return SIGILL;
953 			}
954 			break;
955 		}
956 		break;
957 	}
958 
959 	case d_fmt:{
960 		union {
961 			ieee754dp(*b) (ieee754dp, ieee754dp);
962 			ieee754dp(*u) (ieee754dp);
963 		} handler;
964 
965 		switch (MIPSInst_FUNC(ir)) {
966 			/* binary ops */
967 		case fadd_op:
968 			handler.b = ieee754dp_add;
969 			goto dcopbop;
970 		case fsub_op:
971 			handler.b = ieee754dp_sub;
972 			goto dcopbop;
973 		case fmul_op:
974 			handler.b = ieee754dp_mul;
975 			goto dcopbop;
976 		case fdiv_op:
977 			handler.b = ieee754dp_div;
978 			goto dcopbop;
979 
980 			/* unary  ops */
981 #if __mips >= 2 || defined(__mips64)
982 		case fsqrt_op:
983 			handler.u = ieee754dp_sqrt;
984 			goto dcopuop;
985 #endif
986 #if __mips >= 4 && __mips != 32
987 		case frsqrt_op:
988 			handler.u = fpemu_dp_rsqrt;
989 			goto dcopuop;
990 		case frecip_op:
991 			handler.u = fpemu_dp_recip;
992 			goto dcopuop;
993 #endif
994 #if __mips >= 4
995 		case fmovc_op:
996 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
997 			if (((ctx->fcr31 & cond) != 0) !=
998 				((MIPSInst_FT(ir) & 1) != 0))
999 				return 0;
1000 			DPFROMREG(rv.d, MIPSInst_FS(ir));
1001 			break;
1002 		case fmovz_op:
1003 			if (xcp->regs[MIPSInst_FT(ir)] != 0)
1004 				return 0;
1005 			DPFROMREG(rv.d, MIPSInst_FS(ir));
1006 			break;
1007 		case fmovn_op:
1008 			if (xcp->regs[MIPSInst_FT(ir)] == 0)
1009 				return 0;
1010 			DPFROMREG(rv.d, MIPSInst_FS(ir));
1011 			break;
1012 #endif
1013 		case fabs_op:
1014 			handler.u = ieee754dp_abs;
1015 			goto dcopuop;
1016 
1017 		case fneg_op:
1018 			handler.u = ieee754dp_neg;
1019 			goto dcopuop;
1020 
1021 		case fmov_op:
1022 			/* an easy one */
1023 			DPFROMREG(rv.d, MIPSInst_FS(ir));
1024 			goto copcsr;
1025 
1026 			/* binary op on handler */
1027 		      dcopbop:{
1028 				ieee754dp fs, ft;
1029 
1030 				DPFROMREG(fs, MIPSInst_FS(ir));
1031 				DPFROMREG(ft, MIPSInst_FT(ir));
1032 
1033 				rv.d = (*handler.b) (fs, ft);
1034 				goto copcsr;
1035 			}
1036 		      dcopuop:{
1037 				ieee754dp fs;
1038 
1039 				DPFROMREG(fs, MIPSInst_FS(ir));
1040 				rv.d = (*handler.u) (fs);
1041 				goto copcsr;
1042 			}
1043 
1044 			/* unary conv ops */
1045 		case fcvts_op:{
1046 			ieee754dp fs;
1047 
1048 			DPFROMREG(fs, MIPSInst_FS(ir));
1049 			rv.s = ieee754sp_fdp(fs);
1050 			rfmt = s_fmt;
1051 			goto copcsr;
1052 		}
1053 		case fcvtd_op:
1054 			return SIGILL;	/* not defined */
1055 
1056 		case fcvtw_op:{
1057 			ieee754dp fs;
1058 
1059 			DPFROMREG(fs, MIPSInst_FS(ir));
1060 			rv.w = ieee754dp_tint(fs);	/* wrong */
1061 			rfmt = w_fmt;
1062 			goto copcsr;
1063 		}
1064 
1065 #if __mips >= 2 || defined(__mips64)
1066 		case fround_op:
1067 		case ftrunc_op:
1068 		case fceil_op:
1069 		case ffloor_op:{
1070 			unsigned int oldrm = ieee754_csr.rm;
1071 			ieee754dp fs;
1072 
1073 			DPFROMREG(fs, MIPSInst_FS(ir));
1074 			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
1075 			rv.w = ieee754dp_tint(fs);
1076 			ieee754_csr.rm = oldrm;
1077 			rfmt = w_fmt;
1078 			goto copcsr;
1079 		}
1080 #endif
1081 
1082 #if defined(__mips64)
1083 		case fcvtl_op:{
1084 			ieee754dp fs;
1085 
1086 			DPFROMREG(fs, MIPSInst_FS(ir));
1087 			rv.l = ieee754dp_tlong(fs);
1088 			rfmt = l_fmt;
1089 			goto copcsr;
1090 		}
1091 
1092 		case froundl_op:
1093 		case ftruncl_op:
1094 		case fceill_op:
1095 		case ffloorl_op:{
1096 			unsigned int oldrm = ieee754_csr.rm;
1097 			ieee754dp fs;
1098 
1099 			DPFROMREG(fs, MIPSInst_FS(ir));
1100 			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
1101 			rv.l = ieee754dp_tlong(fs);
1102 			ieee754_csr.rm = oldrm;
1103 			rfmt = l_fmt;
1104 			goto copcsr;
1105 		}
1106 #endif /* __mips >= 3 */
1107 
1108 		default:
1109 			if (MIPSInst_FUNC(ir) >= fcmp_op) {
1110 				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1111 				ieee754dp fs, ft;
1112 
1113 				DPFROMREG(fs, MIPSInst_FS(ir));
1114 				DPFROMREG(ft, MIPSInst_FT(ir));
1115 				rv.w = ieee754dp_cmp(fs, ft,
1116 					cmptab[cmpop & 0x7], cmpop & 0x8);
1117 				rfmt = -1;
1118 				if ((cmpop & 0x8)
1119 					&&
1120 					ieee754_cxtest
1121 					(IEEE754_INVALID_OPERATION))
1122 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
1123 				else
1124 					goto copcsr;
1125 
1126 			}
1127 			else {
1128 				return SIGILL;
1129 			}
1130 			break;
1131 		}
1132 		break;
1133 	}
1134 
1135 	case w_fmt:{
1136 		ieee754sp fs;
1137 
1138 		switch (MIPSInst_FUNC(ir)) {
1139 		case fcvts_op:
1140 			/* convert word to single precision real */
1141 			SPFROMREG(fs, MIPSInst_FS(ir));
1142 			rv.s = ieee754sp_fint(fs.bits);
1143 			rfmt = s_fmt;
1144 			goto copcsr;
1145 		case fcvtd_op:
1146 			/* convert word to double precision real */
1147 			SPFROMREG(fs, MIPSInst_FS(ir));
1148 			rv.d = ieee754dp_fint(fs.bits);
1149 			rfmt = d_fmt;
1150 			goto copcsr;
1151 		default:
1152 			return SIGILL;
1153 		}
1154 		break;
1155 	}
1156 
1157 #if defined(__mips64)
1158 	case l_fmt:{
1159 		switch (MIPSInst_FUNC(ir)) {
1160 		case fcvts_op:
1161 			/* convert long to single precision real */
1162 			rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);
1163 			rfmt = s_fmt;
1164 			goto copcsr;
1165 		case fcvtd_op:
1166 			/* convert long to double precision real */
1167 			rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);
1168 			rfmt = d_fmt;
1169 			goto copcsr;
1170 		default:
1171 			return SIGILL;
1172 		}
1173 		break;
1174 	}
1175 #endif
1176 
1177 	default:
1178 		return SIGILL;
1179 	}
1180 
1181 	/*
1182 	 * Update the fpu CSR register for this operation.
1183 	 * If an exception is required, generate a tidy SIGFPE exception,
1184 	 * without updating the result register.
1185 	 * Note: cause exception bits do not accumulate, they are rewritten
1186 	 * for each op; only the flag/sticky bits accumulate.
1187 	 */
1188 	ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1189 	if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1190 		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */
1191 		return SIGFPE;
1192 	}
1193 
1194 	/*
1195 	 * Now we can safely write the result back to the register file.
1196 	 */
1197 	switch (rfmt) {
1198 	case -1:{
1199 #if __mips >= 4
1200 		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
1201 #else
1202 		cond = FPU_CSR_COND;
1203 #endif
1204 		if (rv.w)
1205 			ctx->fcr31 |= cond;
1206 		else
1207 			ctx->fcr31 &= ~cond;
1208 		break;
1209 	}
1210 	case d_fmt:
1211 		DPTOREG(rv.d, MIPSInst_FD(ir));
1212 		break;
1213 	case s_fmt:
1214 		SPTOREG(rv.s, MIPSInst_FD(ir));
1215 		break;
1216 	case w_fmt:
1217 		SITOREG(rv.w, MIPSInst_FD(ir));
1218 		break;
1219 #if defined(__mips64)
1220 	case l_fmt:
1221 		DITOREG(rv.l, MIPSInst_FD(ir));
1222 		break;
1223 #endif
1224 	default:
1225 		return SIGILL;
1226 	}
1227 
1228 	return 0;
1229 }
1230 
1231 int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1232 	int has_fpu)
1233 {
1234 	unsigned long oldepc, prevepc;
1235 	mips_instruction insn;
1236 	int sig = 0;
1237 
1238 	oldepc = xcp->cp0_epc;
1239 	do {
1240 		prevepc = xcp->cp0_epc;
1241 
1242 		if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
1243 			fpuemustats.errors++;
1244 			return SIGBUS;
1245 		}
1246 		if (insn == 0)
1247 			xcp->cp0_epc += 4;	/* skip nops */
1248 		else {
1249 			/*
1250 			 * The 'ieee754_csr' is an alias of
1251 			 * ctx->fcr31.  No need to copy ctx->fcr31 to
1252 			 * ieee754_csr.  But ieee754_csr.rm is ieee
1253 			 * library modes. (not mips rounding mode)
1254 			 */
1255 			/* convert to ieee library modes */
1256 			ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
1257 			sig = cop1Emulate(xcp, ctx);
1258 			/* revert to mips rounding mode */
1259 			ieee754_csr.rm = mips_rm[ieee754_csr.rm];
1260 		}
1261 
1262 		if (has_fpu)
1263 			break;
1264 		if (sig)
1265 			break;
1266 
1267 		cond_resched();
1268 	} while (xcp->cp0_epc > prevepc);
1269 
1270 	/* SIGILL indicates a non-fpu instruction */
1271 	if (sig == SIGILL && xcp->cp0_epc != oldepc)
1272 		/* but if epc has advanced, then ignore it */
1273 		sig = 0;
1274 
1275 	return sig;
1276 }
1277 
1278 #ifdef CONFIG_DEBUG_FS
1279 extern struct dentry *mips_debugfs_dir;
1280 static int __init debugfs_fpuemu(void)
1281 {
1282 	struct dentry *d, *dir;
1283 	int i;
1284 	static struct {
1285 		const char *name;
1286 		unsigned int *v;
1287 	} vars[] __initdata = {
1288 		{ "emulated", &fpuemustats.emulated },
1289 		{ "loads",    &fpuemustats.loads },
1290 		{ "stores",   &fpuemustats.stores },
1291 		{ "cp1ops",   &fpuemustats.cp1ops },
1292 		{ "cp1xops",  &fpuemustats.cp1xops },
1293 		{ "errors",   &fpuemustats.errors },
1294 	};
1295 
1296 	if (!mips_debugfs_dir)
1297 		return -ENODEV;
1298 	dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
1299 	if (!dir)
1300 		return -ENOMEM;
1301 	for (i = 0; i < ARRAY_SIZE(vars); i++) {
1302 		d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v);
1303 		if (!d)
1304 			return -ENOMEM;
1305 	}
1306 	return 0;
1307 }
1308 __initcall(debugfs_fpuemu);
1309 #endif
1310